If you are using NHibernate for data access, and have to access more than one database, then you need a way of managing multiple Session Factories.
Ideally, your repositories (or whatever) would only take a dependency on an ISession, without needing to know where it came from (DIP). But if you’re getting these repositories out of a container, then you have a problem. How do you provide a different ISession to different instances?
One solution is to use named instances. The following example is for StructureMap, other containers are available. :)
public class NHibernateRegistry : Registry
{
public NHibernateRegistry()
{
const string connectionString1 = "theNameOfAConnectionStringInAppConfig";
const string connectionString2 = "theNameOfADifferentConnectionStringInAppConfig";
For<ISessionFactory>()
.Singleton()
.Use(SessionFactory.BuildFor(connectionString1))
.Named(connectionString1);
For<ISessionFactory>()
.Singleton()
.Use(SessionFactory.BuildFor(connectionString2))
.Named(connectionString2);
For<ISession>()
.Use(c => c.GetInstance<ISessionFactory>(connectionString1).OpenSession())
.Named(connectionString1);
For<ISession>()
.Use(c => c.GetInstance<ISessionFactory>(connectionString2).OpenSession())
.Named(connectionString2);
For<ISomethingRepository>()
.Ctor<ISession>("session").Use(c => c.GetInstance<ISession>(connectionString1));
For<ISomethingElseRepository>()
.Ctor<ISession>("session").Use(c => c.GetInstance<ISession>(connectionString2));
}
}
Or maybe, in the future, just:
For<ISomethingElseRepository>()
.Ctor<ISession>("session").Named(connectionString2);
One thought on “Managing multiple Session Factories using named instances”