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”