Miałem problemy kilka miesięcy temu. Mój problem dotyczył MS SQL Server i Oracle.
To, co zrobiłem, to utworzenie dwóch oddzielnych plików konfiguracyjnych dla nhibernate:
sql.nhibernate.config
<?xml version="1.0" encoding="utf-8"?>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
<reflection-optimizer use="false" />
<session-factory name="BpSpedizioni.MsSql">
<property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
<property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>
<property name="dialect">NHibernate.Dialect.MsSql2008Dialect</property>
<!-- <property name="connection.connection_string">Data Source=(local); Initial Catalog=NHibernate; Trusted_Connection=true;</property> -->
<property name="current_session_context_class">web</property>
<property name="adonet.batch_size">100</property>
<property name="command_timeout">120</property>
<property name="max_fetch_depth">3</property>
<property name='prepare_sql'>true</property>
<property name="query.substitutions">true 1, false 0, yes 'Y', no 'N'</property>
<property name='proxyfactory.factory_class'>NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle</property>
<mapping assembly="BpSpedizioni.Services"/>
</session-factory>
</hibernate-configuration>
ora.nhibernate.config
<?xml version="1.0" encoding="utf-8"?>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
<reflection-optimizer use="false" />
<session-factory name="BpSpedizioni.Oracle">
<property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
<property name="connection.driver_class">NHibernate.Driver.OracleDataClientDriver</property>
<property name="dialect">NHibernate.Dialect.Oracle10gDialect</property>
<!-- <property name="connection.connection_string">Data Source=(local); Initial Catalog=NHibernate; Trusted_Connection=true;</property> -->
<property name="current_session_context_class">web</property>
<property name="adonet.batch_size">100</property>
<property name="command_timeout">120</property>
<property name="max_fetch_depth">3</property>
<property name='prepare_sql'>true</property>
<property name="query.substitutions">true 1, false 0, yes 'Y', no 'N'</property>
<property name='proxyfactory.factory_class'>NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle</property>
<mapping assembly="BpSpedizioni.Services"/>
</session-factory>
</hibernate-configuration>
Używam tej prostej klasy do budowy mojej nhibernate SessionFactory:
public class NHibernateSessionFactory
{
private ISessionFactory sessionFactory;
private readonly string ConnectionString = "";
private readonly string nHibernateConfigFile = "";
public NHibernateSessionFactory(String connectionString, string nHConfigFile)
{
this.ConnectionString = connectionString;
this.nHibernateConfigFile = nHConfigFile;
}
public ISessionFactory SessionFactory
{
get { return sessionFactory ?? (sessionFactory = CreateSessionFactory()); }
}
private ISessionFactory CreateSessionFactory()
{
Configuration cfg;
cfg = new Configuration().Configure(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, this.nHibernateConfigFile));
// With this row below Nhibernate searches for the connection string inside the App.Config.
// cfg.SetProperty(NHibernate.Cfg.Environment.ConnectionStringName, System.Environment.MachineName);
cfg.SetProperty(NHibernate.Cfg.Environment.ConnectionString, this.ConnectionString);
#if DEBUG
cfg.SetProperty(NHibernate.Cfg.Environment.GenerateStatistics, "true");
cfg.SetProperty(NHibernate.Cfg.Environment.ShowSql, "true");
#endif
return (cfg.BuildSessionFactory());
}
}
Jak widać, przekazuję do mojej NHibernateSessionFactory parametry połączenia (wolę je zapisać w pliku konfiguracyjnym mojej aplikacji) i nazwę (bez ścieżki) pliku konfiguracyjnego nhibernate.
Osobiście używam kontenera DI (StructureMap) i możesz osiągnąć coś bardzo fajnego definiując klasę rejestru:
public class NhibernateRegistry : Registry
{
public NhibernateRegistry()
{
For<ISessionFactory>()
.Singleton()
.Add(new NHibernateSessionFactory(<oracle connection string>, "ora.nhibernate.config").SessionFactory)
.Named("OracleSF");
For<ISession>()
.HybridHttpOrThreadLocalScoped()
.Add(o => o.GetInstance<ISessionFactory>("OracleSF").OpenSession())
.Named("OracleSession");
For<ISessionFactory>()
.Singleton()
.Add(new NHibernateSessionFactory(<ms sql connection string>, "sql.nhibernate.config").SessionFactory)
.Named("MsSqlSF");
For<ISession>()
.HybridHttpOrThreadLocalScoped()
.Add(o => o.GetInstance<ISessionFactory>("MsSqlSF").OpenSession())
.Named("MsSqlSession");
}
}
w której możesz użyć nazwanych instancji. Moja warstwa usług używa klasy rejestru StructureMap, w której możesz zdefiniować konstruktory:
this.For<IOrdersService>()
.HybridHttpOrThreadLocalScoped()
.Use<OrdersService>()
.Ctor<ISession>("sessionMDII").Is(x => x.TheInstanceNamed("OracleSession"))
.Ctor<ISession>("sessionSpedizioni").Is(x => x.TheInstanceNamed("MsSqlSession"));
W przypadku wdrożenia usługi:
public class OrdersService : IOrdersService
{
private readonly ISession SessionMDII;
private readonly ISession SessionSpedizioni;
public OrdersService(ISession sessionMDII, ISession sessionSpedizioni)
{
this.SessionMDII = sessionMDII;
this.SessionSpedizioni = sessionSpedizioni;
}
...
}