Wednesday, July 27, 2011

Configure NH in code instead of hibernate.cfg.xml

In one of my ASP.Net MVC projects xml file was used for NH configuration (hibernate.cfg.xml) because of historical reasons. It was annoying because settings were stored in several files: web.config and hibernate.cfg.xml. It was double annoying because Fluen NHibernate contains API for configuration (in my project Fluent NH was used as well). But as it often happens I had no time to fix it. Configuration code looked like this:

   1: public class ConfigurationFactory
   2: {
   3:     public Configuration Build(string configurationFile)
   4:     {
   5:         var configuration = new Configuration();
   6:  
   7:         if (string.IsNullOrEmpty(configurationFile))
   8:             configuration.Configure();
   9:         else
  10:             configuration.Configure(configurationFile);
  11:  
  12:         return Fluently.Configure(configuration)
  13:             .Mappings(cfg =>
  14:             {
  15:                 cfg.FluentMappings.AddFromAssemblyOf<UserMap>()
  16:                     .Conventions.Setup(mappings =>
  17:                         {
  18:                             mappings.AddAssembly(typeof(UserMap).Assembly);
  19:                             mappings.Add(ForeignKey.EndsWith("Id"));
  20:                         });
  21:             }).BuildConfiguration();
  22:     }
  23: }

And configuration file is the following:

   1: <hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
   2:   <session-factory>
   3:     <property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>
   4:     <property name="connection.connection_string">...</property>
   5:     <property name="show_sql">false</property>
   6:     <property name="dialect">NHibernate.Dialect.MsSql2005Dialect</property>
   7:     <property name="cache.provider_class">NHibernate.Caches.SysCache.SysCacheProvider,NHibernate.Caches.SysCache</property>
   8:     <property name="cache.use_query_cache">true</property>
   9:     <property name="adonet.batch_size">100</property>
  10:      <property name="proxyfactory.factory_class">NHibernate.ByteCode.LinFu.ProxyFactoryFactory, NHibernate.ByteCode.LinFu</property>
  11:   </session-factory>
  12: </hibernate-configuration>

Recently I had time to fix it and publish it here for quick reference:

   1: public class ConfigurationFactory
   2: {
   3:     public Configuration Build(string connectionString)
   4:     {
   5:         if (string.IsNullOrEmpty(connectionString))
   6:         {
   7:             connectionString =
   8:                 ConfigurationManager.ConnectionStrings["connectionStringName"].ConnectionString;
   9:         }
  10:  
  11:         return Fluently.Configure()
  12:             .Database(
  13:                 MsSqlConfiguration.MsSql2005
  14:                     .Cache(c => c
  15:                         .UseQueryCache()
  16:                         .ProviderClass<SysCacheProvider>())
  17:                     .ConnectionString(connectionString)
  18:                     .AdoNetBatchSize(100)
  19:                     .DoNot.ShowSql()
  20:                     .ProxyFactoryFactory(typeof(ProxyFactoryFactory))
  21:             )
  22:             .Mappings(cfg =>
  23:             {
  24:                 cfg.FluentMappings.AddFromAssemblyOf<UserMap>()
  25:                     .Conventions.Setup(mappings =>
  26:                         {
  27:                             mappings.AddAssembly(typeof(UserMap).Assembly);
  28:                             mappings.Add(ForeignKey.EndsWith("Id"));
  29:                         });
  30:             }).BuildConfiguration();
  31:     }
  32: }

Here we read connection string from web.config and do the rest actions via Fluent configuration API. After that hibernate.cfg.xml can be finally removed from the project.

No comments:

Post a Comment