March 2009


For the next rev of dashCommerce, we are going to be using NHibernate and so I have been exploring ways to both: 1.) get up to speed with NHibernate and 2.) the fastest way to get started working with NHibernate. I had seen all of the articles on Fluent NHibernate, but to me it just looked like a C# version of Xml. That’s not a ding against, it, but when you have system with about 50 tables in it, well . . . typing is typing. :)

But, one thing that caught my eye when I started looking around the Fluent NHibernate project was the AutoMapping feature. This feature will allow you to set up some conventions for use against your database and it will attempt to generate the mapping files for you. That’s pretty slick. :D But would it work well enough to actually use since Fluent NHibernate is still pretty young?

Well, it worked well enough for me. :)

So, here is what I had to do to pull it off against the dashCommerce database.

When I started trying to get the mappings to work against a bunch of dashCommerce tables, I was getting some errors about not being able to map certain entities. So, as soon as I saw that, and recognized that the exception wasn’t going to help me identify what, exactly, the problem was I dug into the code and ended up changing this very simple line in the ClassMap file (public void ApplyMappings(IMappingVisitor visitor)) around line 195: Debug.WriteLine(writer.ToString()); to Console.WriteLine(writer.ToString()); I was using a small console client with some sample queries in it, so this was best for me at the time. But, once I did that, I was able to quickly look at that output and determine the cause of my pains.

To be exact, they were all related to a few key things:

  1. The AutoMap functionality relies on conventions to determine the structure of your database tables.
  2. I had to update the AutoMap conventions with the conventions used by the dashCommerce database.
  3. The dashCommerce database was not entirely consistent in its naming conventions. (gufaw!) ;)

This last one is the one that really appealed to me as I know I put a lot of work into being consistent in the way the dashCommerce database is constructed, but it just showed me where I had missed things. This is great, and showed me the beauty of the AutoMap functionality. And it will be helpful in generating an upgrade script for dashCommerce going forward to ensure the database conventions are consistently applied.

So, how much code did it take to get the AutoMapping functionality working with dashCommerce? Not much. It’s not at 100% coverage yet, but we are in pretty good shape.

One other interesting thing about the AutoMapping in combination with dashCommerce is that in the dC database, we kind of namespace things out so there is a correlation between the assemblies and the database. For instance, we have the following naming conventions: dashCommerce _Core_tableName, dashCommerce_Store_tableName, and dashCommerce_Content_tableName. I’m still hmm’ing and haw’ing over whether or not I really like that anymore, but it does make things very clear for the developer that is customizing dashCommerce. That means it made the conventions less flexible, so I had to accommodate that in the code by creating separate files for each mapping. So, for instance, in getting the Core up and running, the code for Fluent NHibernate AutoMap was as simple* as this:

 

var configuration = MsSqlConfiguration.MsSql2005
    .ConnectionString(connectionString => connectionString
    .Server("MYSERVER")
    .Database("DASHCOMMERCE")
    .Username("USER")
    .Password("PASSWORD"))
    .UseReflectionOptimizer()
    .ConfigureProperties(new Configuration());

var autoPersistenceModel = AutoPersistenceModel
    .MapEntitiesFromAssemblyOf<Log>()
    .Where(type => type.IsClass && !type.IsAbstract && type.Namespace == "Core.Entities")
    .WithConvention(convention =>
    {
    convention.FindIdentity = p => p.Name == p.DeclaringType.Name + "Id";
    convention.GetTableName = type => "dashCommerce_Core_" + type.Name;
    convention.GetPrimaryKeyNameFromType = type => type.Name + "Id";
    convention.GetForeignKeyNameOfParent = prop => prop.Name + "Id";
    })
    ;

 autoPersistenceModel.Configure(configuration);

 

*simple took me a couple of hours, but that was digging into Fluent NHibernate for the first time and trying to grok and learn all at once.

There is still some work to do on Many to Many relationships, but this was darned impressive and a huge boost in productivity for dashCommerce and NHibernate. Thank you to the folks that have created Fluent NHibernate, this makes working with NHibernate easier than any other ORM / code generation tool out there. :)

One other side note worth mentioning is that once you have the AutoMap set up correctly, you can have Fluent NHibernate spit out the mapping files so that you can use those directly (which is what we are doing for dashCommerce).

DotNetKicks Image

In my last post, I profiled what you would need to do to get Visual Studio to use the Mono compiler for compiling your Mono projects. I also created 3 basic Mono project templates that are available for download.

Apparently, they have some appeal as they have been downloaded a couple of hundred times, so that’s good. :) Also, it looks as though Mono is getting some additional traction and good looks from others in the Microsoft community. That is good, it should.

I have also made it a priority for dashCommerce to run on Mono in future revs as I think this is a huge win for software products in general, but especially so for open source projects.

But, one thing that I left out of the previous post was some Mono item templates. Specifically, some standard stock templates because if you add a stock item (like a Web Form) to your project that references .NET assemblies, you will get this lovely little creature when you compile:

NETref 

Which is basically telling you that Mono has no idea what the heck the referenced assembly is! So, how to fix it? Well, you need some item templates that reference the Mono assemblies and not the .NET assemblies.

I have gone ahead and created the following templates for use in your Mono projects:

  • Class
  • Interface
  • Master Page
  • Web Content Form
  • Web Form
  • Web Service
  • Web User Control

You can download these item templates from here (as well as the Project Templates). Once you download them, you can put them in My Documents\Visual Studio 2008\Templates\ItemTemplates\Visual C#\Mono and you should be good to go.

That being said, there was a recent Beta release of MonoDevelop 2.0 and I am hearing good things about it, so all this may be for naught if it is a solid IDE, but I am easing into this and frankly, I think MS and Visual Studio should support development on the Mono platform. But maybe that’s just me. :)

DotNetKicks Image