Tuesday, July 11, 2006

After spending (what to me was) an unbelievable number of hours fighting with css, I have a new web site: www.lhotka.net is now ASP.NET 2.0, with master pages, themes and a pure css layout. Special thanks to Mike Gale for helping me with some issues, and to http://www.positioniseverything.net/ for providing tools that generate various types of css layouts. It continues to amaze me that you need a tool (and various browser-specific hacks) to generate simple tabular page layouts - but I guess that's the web for you...

Anyway, the end result is that the web site is no longer hosted on a ~7 year old dual P3/450 machine with 512 megs of RAM - but rather is hosted on a (relatively) new Athalon 3100 with a couple gigs of RAM. So not only does it look different, but it is a bit faster too :)

However, some of the speed is bled off by my choice to jump into virtualization. The web "server" is actually now a virtual machine. (yes, I know you are supposed to keep these sorts of details private to slow hackers - but sharing information is the key to forward motion...)

I chose to do this because it means I have a lot more flexibility going forward. In particular, if this physical machine were to crash, I could rehost the vhd files on another machine and get running again relatively fast. Trying to do that with an OS directly installed on the hard drive is non-trivial (requiring something like Ghost or Acronis TrueImage).

With the virtualization, I can script it so the VM shuts down, the vhd files are copied elsewhere (as a backup) and the VM is restarted. Full image backups in just a couple minutes! Hard to beat that as a feature!

It is also the case that this server box is largely underutilized. It isn’t like my web site or blog are popular enough to overwhelm the machine. So now I have the ability to host other virtual machines on the same physical box, for testing of beta software or hosting other types of servers if I have the need going forward.

I had also considered moving from cvs to svn at the same time as the rest of the upgrade process. In researching that, I decided there was simply too much risk. While Subversion installed OK, the cvs2svn tool was unable to handle the CSLA .NET code repository. As with many of these tools, it was written by Un*x people for their needs, and has never really be made to work with the Windows equivalent software (cvsnt in my case). While it works for some people, my repository is apparently too old and complex (tagging/branching/deleting of files/directories).

The end result is that switching to svn means abandoning all the history I have in cvs. I’m not quite ready to do that, nor do I want to lose the cvsgraph abilities from viewcv (because there’s no equivalent for svn at present I guess). So for now, at least, I’m sticking with cvs.

Of course the obvious question is why I didn’t switch to Microsoft VSTS/TFS. There are perhaps two good reasons: licensing and functionality. Licensing isn’t a problem for me directly – I have a workgroup license that would serve me fine. But it isn’t clear that I could expose the code repository externally and still satisfy the license – and I think there’s tremendous value in www.lhotka.net/cslacvs... And functionality is an issue too – primarily in that I don’t know of a viewcv equivalent for TFS. So even if licensing is/was a non-issue – the lack of a read-only web viewer for the repository is a show-stopper.

Given time I am sure these issues will work themselves out – so by the time I’m ready to move off cvs perhaps TFS will be a viable choice alongside Subversion. Time will tell…

Tuesday, July 11, 2006 12:31:12 PM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [7]  | 

 Tuesday, June 27, 2006

I am spending a few days working with a client for Magenic, having a great time discussing how to apply and extend CSLA .NET to meet their needs.

The client is from Montreal and so they speak French. Today I learned that CSLA, spoken quickly, sounds like c'est cela in French, which means "That's it".

Hopefully that equates to being cool, or being the "it" solution :)

Tuesday, June 27, 2006 6:43:36 PM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [1]  | 

 Sunday, June 25, 2006

I've never pretended to be a UI expert - especially not for the web. (I am very good at designing heads-down data entry screens that minimize keystrokes and avoid the use of the mouse - but that's far from being good at making things pretty)

So I'm trying to create an updated version of www.lhotka.net. To do this I'm using ASP.NET 2.0 master pages, and avoiding all use of tables - only div statements are allowed. This way I can use ASP.NET 2.0 theme/skin support to get the appearance (working with the div layout in the master page). And it looks pretty good in IE too. After a lot of time figuring out how css works - and how it cascades settings from one level down to the next - it finally looks pretty decent.

So then I open it in Firefox. Apparently FF doesn't follow the same rules at all. Settings don't cascade from one div to a lower div. Settings like height: 100% apparently are ignored entirely. And my content area refuses to sit beside the nav area, and when I manage to get them sitting side-by-side the width is different from the header - since the width apparently didn't cascade from the top-level div tag's style.

No wonder web development is so damn expensive. Doing something simple like laying out a standard page with header/nav/body is apparently radically different between IE and FF. Worse yet, FF must use a totally different mental model... Where Bill Clinton wanted to know the meaning of "is", it appears that FF needs to know the meaning of "cascade"...

Sunday, June 25, 2006 12:52:10 PM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [14]  | 

 Saturday, June 17, 2006

CSLA .NET version 2.0.2 is now available for download at www.lhotka.net/cslanet/download.aspx. This is a bug fix update to address various errata and issues that readers have found since version 2.0.1.

This version also introduces one change, which allows you to call DataPortal.Fetch with no criteria.

Saturday, June 17, 2006 9:53:34 AM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [2]  | 

 Friday, June 09, 2006

According to this blog post by Soma, WinFX is now going to be named .NET 3.0.

Now on one hand this makes sense. There's no doubt that WinFX introduces major functionality to .NET. Windows Presentation Foundation is the effective successor to Windows Forms after all - how much more major can you get??

On the other hand, the new .NET 3.0 doesn't break any .NET 2.0 code, and yet it "includes" .NET 2.0. All .NET 3.0 does is add new stuff. Typically, when I think of a major version number changing, I expect that I'll have to retest everything and that much of my stuff might break or be affected. None of that is happening here.

Even changing from .NET 1.0 to 1.1 brought tons of headaches (if you used Remoting or Enterprise Services at least). And that was a point release. Yet here we have a major version change that doesn't change any existing bits.

I guess it just goes to show that there are no hard-and-fast rules in the software industry ;)

In any case, there's no doubt that Microsoft will reduce confusion overall by keeping everything under the .NET moniker, so I think this is a wise move.

Friday, June 09, 2006 4:54:33 PM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [3]  | 

 Wednesday, May 31, 2006

CSLA .NET version 2.0.1 is now available for download at www.lhotka.net/cslanet/download.aspx. This is primarily a bug fix update to address various errata and issues that readers have found since the release of the original code. It does include a couple changes primarily geared toward simplification of code generation templates. You can see the change log here.

At a high level the changes (other than bug fixes) include:

  • A new Initialize() method for use by code generation templates
  • A new IEditableBusinessObject interface to allow polymorphic child objects in BusinessListBase-derived collections
  • Better support for lazy loading of child collections (EditLevel property now visible from BusinessListBase, and null child object references now restored in UndoChanges)

 

Wednesday, May 31, 2006 9:37:06 PM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [4]  | 

 Thursday, May 25, 2006

According to Bookscan (a service which tracks book sales for all sorts of books), Expert C# 2005 Business Objects is number 365 and Expert VB 2005 Business Objects is number 385 among all computer books out there. This includes consumer-oriented computer books too, so these numbers are incredibly good. Programming books have a hard time competing with consumer books for sales volume after all.

What I find most interesting is that the VB sales are comparable to the C# sales. Obviously there really is a market for higher end VB programming books, which I think validates a view I've held for a long time, that the VB community was waiting for .NET to mature before moving forward. Clearly VS 2005 is triggering a non-trivial movement of VB developers into .NET, and these are hard-core professional developers who are looking for something beyond the reference-style and tutorial style books out there.

Like I said a few months ago, in .NET 1.1 the C# book outsold the VB book rather substantially. These numbers appear to show that the dynamic is changing, and I find that quite exciting!

Thursday, May 25, 2006 2:09:19 PM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [4]  | 

I have two updates for CSLA .NET for those who are interested.

CSLA .NET version 1.53 is now available from www.lhotka.net/cslanet/download10.aspx. This is a minor bug fix update to 1.52.

A beta of CSLA .NET version 2.0.1 is now available from www.lhotka.net/cslanet/download.aspx. This includes fixes for a number of bugs and errata (which you can find at www.lhotka.net/cslanet), as well as some minor enhancements due to unforseen limitations around areas like threading and polymorphic child objects. If you get a chance to try 2.0.1 I would appreciate it. Barring any negative feedback from the community I expect to finalize it in about a week.

Thursday, May 25, 2006 2:01:38 PM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [0]  | 

 Saturday, May 13, 2006

I’ve run into a spot where I’m stuck, and I’m hoping someone has an idea.

 

CSLA .NET 2.0 includes an ASP.NET data source control: CslaDataSource. This works well, except for one issue, which is that it doesn’t refresh the metadata for your business objects unless you close VS 2005 and reopen the IDE.

 

The reason for this problem is that your business assembly gets loaded into memory so the data source control can reflect against it to gather the metadata. That part works fine, but once an assembly is loaded into an AppDomain it can’t be unloaded. It is possible to unload an entire AppDomain however, and so that’s the obvious solution: load the business assembly into a temporary AppDomain.

 

So this is what I’m trying to do, and where I’m stuck. You see VS 2005 has a very complex way of loading assemblies into ASP.NET web projects. It actually appears to use the ASP.NET temporary file scheme to shadow the assemblies as it loads them. Each time you rebuild your solution (or a dependant assembly – like your business assembly), a new shadow directory is created.

 

The CslaDataSource control is loaded into the AppDomain from the first shadow directory – and from what I can tell that AppDomain never unloads, so the control is always running from that first shadow directory. And then – even if I use a temporary AppDomain – the business assembly is also loaded from that same shadow directory, even if newer ones exist.

 

And that’s where I’m stuck. I have no idea how to find out the current shadow directory, and even if I do odd things like hard-coding the directory, then I just get in trouble because the new AppDomain thinks it has a different Csla.dll than the AppDomain hosting the Web Forms designer.

 

Here’s the code that loads the Type object within the temporary AppDomain:

 

    public IDataSourceFieldSchema[] GetFields()

    {

      List<ObjectFieldInfo> result =

        new List<ObjectFieldInfo>();

 

      System.Security.NamedPermissionSet fulltrust =

        new System.Security.NamedPermissionSet("FullTrust");

      AppDomain tempDomain = AppDomain.CreateDomain(

        "__temp",

        AppDomain.CurrentDomain.Evidence,

        AppDomain.CurrentDomain.SetupInformation,

        fulltrust,

        new System.Security.Policy.StrongName[] { });

      try

      {

        // load the TypeLoader object in the temp AppDomain

        Assembly thisAssembly = Assembly.GetExecutingAssembly();

        int id = AppDomain.CurrentDomain.Id;

        TypeLoader loader =

          (TypeLoader)tempDomain.CreateInstanceFromAndUnwrap(

            thisAssembly.CodeBase, typeof(TypeLoader).FullName);

        // load the business type in the temp AppDomain

        Type t = loader.GetType(

          _typeAssemblyName, _typeName);

       

        // load the metadata from the Type object

        if (typeof(IEnumerable).IsAssignableFrom(t))

        {

          // this is a list so get the item type

          t = Utilities.GetChildItemType(t);

        }

        PropertyDescriptorCollection props =

          TypeDescriptor.GetProperties(t);

        foreach (PropertyDescriptor item in props)

          if (item.IsBrowsable)

            result.Add(new ObjectFieldInfo(item));

      }

      finally

      {

        AppDomain.Unload(tempDomain);

      }

      return result.ToArray();

    }

 

This replaces the method of the same name from ObjectViewSchema in the book.

 

Notice that it creates a new AppDomain and then invokes a TypeLoader class inside that AppDomain to create the Type object for the business class. The TypeLoader is a new class in Csla.dll that looks like this:

 

using System;

using System.Collections.Generic;

using System.Text;

 

namespace Csla.Web.Design

{

  /// <summary>

  /// Loads a Type object into the AppDomain.

  /// </summary>

  public class TypeLoader : MarshalByRefObject

  {

    /// <summary>

    /// Returns a <see cref="Type">Type</see> object based on the

    /// assembly and type information provided.

    /// </summary>

    /// <param name="assemblyName">(Optional) Assembly name containing the type.</param>

    /// <param name="typeName">Full type name of the class.</param>

    /// <remarks></remarks>

    public Type GetType(

      string assemblyName, string typeName)

    {

      int id = AppDomain.CurrentDomain.Id;

      return Csla.Web.CslaDataSource.GetType(

        assemblyName, typeName);

    }

  }

}

 

Since this object is created in the temporary AppDomain, the business assembly is loaded into that AppDomain. The Type object is [Serializable] and so is serialized back to the main AppDomain so the data source control can get the metadata as needed.

 

This actually all works – except that it doesn’t pick up new shadow directories as they are created.

 

Any ideas on how to figure out the proper shadow directory are appreciated.

 

Honestly, I can’t figure out how this works in general – because obviously some part of the VS designer picks up the new shadow directory and uses it – even though the designer apparently doesn’t. I am quite lost here.

 

To make matters worse, things operate entirely differently when a debugger is attached to VS than when not. When a debugger is attached to VS then nothing appears to pick up the new shadow directories – so I assume the debugger is interfering somehow. But it makes tracking down the issues really hard.

Saturday, May 13, 2006 12:53:49 PM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [14]  |