Using Sharp Lite with Fluent nHibernate

One thing I didn't liked too much when first met S#arp Lite was the fact that Billy McCafferty decided to drop Fluent nHibernate as the defacto mapper for entities. There was a big discussion on the matter of nHibernate making it's own fluent (or was it Loquacious?) API to map entities on a lot of places, and finally James Gregory, the man who gave us Fluent nHibernate spoke on the matter of nHibernate making an API that looked a lot like his.

The conclusion is pretty simple, Fluent nHibernate is not dead, not even close, there are a lot of folks (me included) that like it and we are not willing to let it go. Having said that, I wanted to integrate my Fluent nHibernate into S#arp Lite, and just as Billy said, is a dead simple thing to do, still will share it here.

The first thing you need to do is to reference the Fluent nHibernate library from your NorthwindDemo.NHibernateProvider project, so you can use it there. After that, you can make your own mappings on the provider. If you don't know what is a Fluent Mapping, you should read this wiki before you start here. Now that we have our mappings made, we need to change the nHibernate boot process found in NHibernateInitializer so we use Fluent nHibernate instead. Go to the NHibernateInitializer class and change the code for this:

public static Configuration Initialize()
{
 var cnf 
          = Fluently.Configure()
      .Database(MySQLConfiguration.Standard.ConnectionString( 
    x => x.Database("MyDb")
          .Username("MyUserName")
          .Password("MyPassword")
          .Server("MyServer"))
   )
       .Mappings( m => m.FluentMappings.AddFromAssemblyOf<CustomerMapping>());

 var configuration 
          = cnf.BuildConfiguration()
        .Proxy( p => p.ProxyFactoryFactory<DefaultProxyFactoryFactory>() )
        .CurrentSessionContext<LazySessionContext>();

 return configuration;
} 
 

Notice that I'm not using SQL Express like the default install uses, I'm using MySQL instead. The magic of the thing is on the line:

.Mappings( m => m.FluentMappings.AddFromAssemblyOf()); 
 

Here, I'm telling FNH to load all the mappings specified in the assembly of CustomerMapping, which is one of my entities' mappings. After that, we register the DefaultProxyFactoryFactory to manage the lazy loading, which basically gets rid of the old nHibernate.Castle so we don't have to use an external loader for proxy classes. With this configuration, you should be on your way to use Fluent nHibernate with your S#arp Lite project.

Finally, there is one thing. I think, not so sure though, that there is a version of Fluent NH for nHibernate 3.2, however, if you are using an older one, like me!, I'm using v1.2 which looks for nHibernate 3.1, you will need to make an Assembly redirect, which is easy, just lk in your web.config file for this line:

<runtime>
 <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
  <dependentAssembly>
   <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
   <bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="3.0.0.0" />
  </dependentAssembly>
 </assemblyBinding>
</runtime>
 

And change it for this one:

<runtime>
 <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
  <dependentAssembly>
   <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
   <bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="3.0.0.0" />
  </dependentAssembly>
  <dependentAssembly>
   <assemblyIdentity name="NHibernate" publicKeyToken="aa95f207798dfdb4" culture="neutral" />
   <bindingRedirect oldVersion="0.0.0.0-3.1.0.4000" newVersion="3.2.0.4000" />
  </dependentAssembly>
 </assemblyBinding>
</runtime>
 

The basic idea is to tell the system that when someone (FNH) asks for nHibernate from version 0.0.0.0 to 3.1.0.4000 the assembly to resolve is version 3.2.0.4000, so the binding is done properly. This should be it, you should have your own S#arp Lite project running on Fluent nHibernate!!

Happy coding! And as usual, comenting is not forbidden ;)

2 comments:

  1. This is great David. I have to admit, I'm still not completely sold on Loquacious configuration. To me, Fluent NHibernate is so more descriptive...Loquacious is still quite cryptic to me. So having these instructions is a great alternative to have available for those who don't want to drink the new configuration Kool-Aid. ;)

    ReplyDelete
  2. Pawel Procaj5 April 2013 12:19

    Hi, David. I've got one problem with this FluentNH configuration. Could you please post an example of your mapping?
    Do you have a separate mapping class for the SharpLite.Domain.Entity class?

    In my situation I can see that Mapping classes are initialized (I put a breakpoint in the constructor of one of them) but later on they are not seen by the framework, somehow...
    I'm getting an exception: No persister for: [MyApp.Domain.Model] when trying to save a new instance of the model class.

    My Fluent configuration is following:

    return Fluently.Configure()
    .Database(MsSqlConfiguration.MsSql2008.ConnectionString(
    x => x.FromConnectionStringWithKey("MyConnectionString"))
    .ShowSql())

    //2nd level cache
    .Cache(
    c => c.UseQueryCache()
    .UseSecondLevelCache()
    .ProviderClass())

    .Mappings(m => m.FluentMappings.AddFromAssemblyOf())

    .ProxyFactoryFactory()
    .CurrentSessionContext()
    .BuildConfiguration();


    Do you have any clue why there is that persister-related exception?

    Best regards
    Pawel Procaj

    ReplyDelete

Commenting is allowed!