public global::NHibernate.Cfg.Configuration BuildConfiguration(bool showSql, out NhConfigurationCacheKey configurationCacheKey, string connReleaseMode) { return(CreateConfiguration(_nhDriver, ConnectionString, GetRdbmsMapsAssembly(), showSql, true, _sessionContext, _outputNhMappings, _useNhProfiler, out configurationCacheKey, connReleaseMode)); }
public static global::NHibernate.Cfg.Configuration CreateConfiguration(SupportedNHDrivers nhDriver, string connectionString, Assembly fluentMappingsAssembly, bool showSql, bool enablePostCommitListener, string sessionContext, bool outputNhMappings, bool useNhProfiler, out NhConfigurationCacheKey configurationCacheKey, string connReleaseMode) { Mandate.ParameterNotNullOrEmpty(connectionString, "connectionString"); Mandate.ParameterNotNull(fluentMappingsAssembly, "fluentMappingsAssembly"); Mandate.ParameterCondition(nhDriver != SupportedNHDrivers.Unknown, "nhDriver"); configurationCacheKey = new NhConfigurationCacheKey( nhDriver, connectionString, fluentMappingsAssembly, showSql, enablePostCommitListener, sessionContext, outputNhMappings); return(ConfigurationCache.GetOrAdd( configurationCacheKey, y => { using (new WriteLockDisposable(MappingLocker)) { if (useNhProfiler) { try { NHibernateProfiler.Initialize(); } catch (InvalidOperationException ex) { //swallow security exceptions, happens if running in Medium trust if (!(ex.InnerException is SecurityException)) { throw ex; } } } // Check if we already have a serialized Configuration object // for this assembly version and assembly last-write date using (new WriteLockDisposable(ConfigCacheLocker)) if (ConfigCacheFileExists(connectionString)) { var cachedConfig = DeserializeConfig(connectionString); if (cachedConfig != null) { return cachedConfig; } } // We haven't cached config before, or couldn't load it, so dynamically create it // Figure out the FluentNH persistence configurer based on the desired driver var persistenceConfigurer = GetPersistenceConfigurer(nhDriver, connectionString); // Figure out the connection release mode to use, because SqlCe needs "on_close" for perf reasons, // whereas we should use "auto" for everything else to avoid long-running connections var trueConnReleaseMode = connReleaseMode; // Could have been set already by a unit test if (connReleaseMode == NHibernateConfigBuilder.CustomConnReleaseMode) // Only modify if it's a value teling us to modify { if (nhDriver == SupportedNHDrivers.MsSqlCe4) { trueConnReleaseMode = "on_close"; } else { trueConnReleaseMode = "auto"; } } // Configure NH using FluentNH var fluentConfig = Fluently.Configure().Database(persistenceConfigurer) //.Cache(x => // x.UseMinimalPuts() // .UseQueryCache() // .UseSecondLevelCache() // .ProviderClass(typeof(global::NHibernate.Caches.SysCache2.SysCacheProvider).AssemblyQualifiedName)) // after_transaction does not work for unit tests with Sqlite .ExposeConfiguration(c => c.SetProperty(Environment.ReleaseConnections, trueConnReleaseMode) .SetProperty(Environment.CurrentSessionContextClass, sessionContext) .SetProperty(Environment.GenerateStatistics, useNhProfiler.ToString().ToLower()) .SetProperty(Environment.BatchSize, "20") .SetProperty(Environment.ProxyFactoryFactoryClass, typeof(ProxyFactoryFactory).AssemblyQualifiedName)) .Mappings(x => { // Add named queries from our embedded mappings file x.HbmMappings.AddFromAssembly(fluentMappingsAssembly); // Add class mappings var container = x.FluentMappings.AddFromAssembly(fluentMappingsAssembly); AddConventions(nhDriver, container.Conventions); }); if (showSql) { fluentConfig.ExposeConfiguration(c => c.SetProperty(Environment.ShowSql, "true")); } try { // Generate the NHibernate configuration object from FluentNH var nhConfig = fluentConfig.BuildConfiguration(); // Add a PostCommitInsert listener which is responsible for passing generated IDs back to the // mapped entities for entity insert scenarios (since the NH mapped objects aren't passed outside // of this provider) if (enablePostCommitListener) { var entitySaveEventListener = new NhEventListeners(); nhConfig.SetListener(ListenerType.PostInsert, entitySaveEventListener); nhConfig.SetListener(ListenerType.PostUpdate, entitySaveEventListener); nhConfig.SetListener(ListenerType.PostCommitInsert, entitySaveEventListener); nhConfig.SetListener(ListenerType.PreDelete, entitySaveEventListener); nhConfig.SetListener(ListenerType.Delete, entitySaveEventListener); nhConfig.SetListener(ListenerType.Merge, entitySaveEventListener); nhConfig.SetListener(ListenerType.SaveUpdate, entitySaveEventListener); nhConfig.SetListener(ListenerType.Flush, entitySaveEventListener); nhConfig.SetListener(ListenerType.Evict, entitySaveEventListener); nhConfig.SetListener(ListenerType.PreDelete, entitySaveEventListener); } // Add the Aggregate interceptor for running trigger-like actions that NH can't handle // Disabled, done by event listener instead now: nhConfig.SetInterceptor(new AggregateDataInterceptor()); // Add the FluentNH persistence model and configure NH to use it var fluentAutoModel = new AutoPersistenceModel(); fluentAutoModel.AddMappingsFromAssembly(fluentMappingsAssembly); fluentAutoModel.BuildMappings(); fluentAutoModel.Configure(nhConfig); if (outputNhMappings) { var codeBase = Assembly.GetExecutingAssembly().CodeBase; var uri = new Uri(codeBase); var path = uri.LocalPath; var binFolder = new DirectoryInfo(Path.GetDirectoryName(path)); string nhibernateOutputFolder; if (binFolder.Name == "Debug") { nhibernateOutputFolder = Path.Combine( binFolder.Parent.Parent.FullName, "App_Data", "Logs", "NHibernateConfig"); } else { //its just 'bin' nhibernateOutputFolder = Path.Combine( binFolder.Parent.FullName, "App_Data", "Logs", "NHibernateConfig"); } Directory.CreateDirectory(nhibernateOutputFolder); fluentAutoModel.WriteMappingsTo(nhibernateOutputFolder); } SaveConfigurationToFile(nhConfig, connectionString); return nhConfig; } catch (Exception ex) { throw new InvalidOperationException("Cannot build NHibernate configuration", ex); } } })); }