Reputation: 137
Using: ASP.NET MVC3 Ninject 2 Fluent nHibernate
I have 2 databases (DB1 & DB2). I have one base repository class (Repository) and many Controllers (Controller1, Controller2).
public MyController(IRepository<SomeModelFromDB1> someModelFromDB1Repository, IRepository<SomeModelFromDB2> someModelFromDB2Repository)
{
[...]
}
public class Repository<T> : IRepository<T> where T : Entity
{
private readonly ISession _session;
public Repository(ISessionFactory sessionFactory)
{
_session = sessionFactory.OpenSession();
}
}
public class DB1SessionFactory : ISessionFactory
{
private readonly NHibernate.ISessionFactory _sessionFactory;
private ISession _session;
public DB1SessionFactory()
{
[...]
}
}
public class DB2SessionFactory : ISessionFactory
{
private readonly NHibernate.ISessionFactory _sessionFactory;
private ISession _session;
public DB2SessionFactory()
{
[...]
}
}
Now when I create MyController. I want my repository injected, but that repository should use DB1 (or DB2, depending on the model) SessionFactory.
I cannot figure how to properly inject it all... When I had only a single SessionFactory (DB1), here what I had with NINJECT:
kernel.Bind<ISessionFactory>().To<DB1SessionFactory>()
.InRequestScope();
kernel.Bind(typeof(IRepository<>)).To(typeof(Repository<>));
Edit:
The best would be that the right session is injected in the repository depending on the model. Since some models are from DB1 and others from DB2, the choice should be dependent from it. It would be great also if the controller/view developer not have to bother with anything (like having [Named] in front of the repository) but if it's what it takes. Even with [Named], I couldn't figure how to inject the right session in the repository based on the [Named] repository in the controller...
Upvotes: 3
Views: 1661
Reputation: 32725
First of all, you should define the session factory in singelton scope and have the session in request scope.
Do the configuration like this:
.Bind<ISessionFactory>().To<DB1SessionFactory>().Named("DB1")
.InSingletonScope();
.Bind<ISessionFactory>().To<DB2SessionFactory>().Named("DB2")
.InSingletonScope();
private bool IsOnDB(IRequest request, string dbName)
{
var repositoryType = request.ParentRequest.Service;
var modelType = repositoryType.GetGenericArguments()[0];
var databaseName = this.GetDatabaseForModel(modelType);
return databaseName == dbName;
}
.Bind<ISession>()
.ToMethod(ctx => ctx.Kernel.Get<ISessionProvider>("DB1").OpenSession())
.When(r => this.IsOnDb(r, "DB1"))
.InRequestScope();
.Bind<ISession>()
.ToMethod(ctx => ctx.Kernel.Get<ISessionProvider>("DB2").OpenSession())
.When(r => this.IsOnDb(r, "DB2"))
.InRequestScope();
Upvotes: 3