Archive for December, 2010

Upgrade to NHibernate 3.0 and FluentNHibernate 1.2.0

Tuesday, December 21st, 2010

We had some problems loading multiple assemblies when we upgraded from NHibernate2.1.2 to NHibernate3.0.

Here is the setup of loading all mapping files from all the assemblies that have mappingfiles, that we succesfully used for NH2.1.2.


private static FluentConfiguration CreateNHibernateConfiguration()
{
// reads settings from config
Configuration nHibernateConfiguration = new NHibernate.Cfg.Configuration();
// configure default NHibernate
nHibernateConfiguration.Configure();
// pass the default configuration into FluentNHibernate
FluentConfiguration configuration = Fluently.Configure(nHibernateConfiguration);

string[] assemblies = {
"My.AssemblyA",
"My.AssemblyB",
"My.AssemblyC",
// etc, cut for brevity; all assemblies containing
// either *.hbm.xml mappings and/or Fluent mappings
};

foreach (string name in assemblies)
{
Assembly assembly = Assembly.Load(name);
// combination of normal and fluent mappings:
configuration.Mappings(m =>
{
m.FluentMappings.AddFromAssembly(assembly);// .ExportTo(@"D:\EXPORT\");
m.HbmMappings.AddFromAssembly(assembly);
});
return configuration;
}
}

Unfortunately, the above code does NOT work when we upgraded to NHibernate 3.0 with its accompanying FluentNHibernate release. After some investigation it turned out that within the loop of the assemblies, only the classmaps of the last assembly remained in the configuration.

We had to change the above piece of code to the following to have it work for FluentNHibernate:


private static FluentConfiguration CreateNHibernateConfiguration()
{
// reads settings from config
Configuration nHibernateConfiguration = new NHibernate.Cfg.Configuration();
// configure default NHibernate
nHibernateConfiguration.Configure();
// pass the default configuration into FluentNHibernate
FluentConfiguration configuration = Fluently.Configure(nHibernateConfiguration);

string[] assemblies = {
"My.AssemblyA",
"My.AssemblyB",
"My.AssemblyC",
// etc, cut for brevity; all assemblies containing
// either *.hbm.xml mappings and/or Fluent mappings
};
// here is the difference from previous example:
configuration.Mappings(m => {
foreach (string name in assemblies)
{
Assembly assembly = Assembly.Load(name);
// combination of normal and fluent mappings:
m.FluentMappings.AddFromAssembly(assembly);// .ExportTo(@"D:\EXPORT\");
m.HbmMappings.AddFromAssembly(assembly);
}
}).
return configuration;
}

Note; this is example code, some try..catch..log/debug.writeline blocks have been removed for readability.

As you can see, we had to get the lambda expression at the top and thus -around- the assemblyloop instead of inside the loop. This was probably needed because of the internal changes within the FluentNhibernate.AddFromAssembly code, but we’re not entirely sure.