Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net mvc 如何将不同的NHibernate会话(多数据库)注入到同一个存储库中,控制器通过Ninject控制哪些会话_Asp.net Mvc_Nhibernate_Ninject - Fatal编程技术网

Asp.net mvc 如何将不同的NHibernate会话(多数据库)注入到同一个存储库中,控制器通过Ninject控制哪些会话

Asp.net mvc 如何将不同的NHibernate会话(多数据库)注入到同一个存储库中,控制器通过Ninject控制哪些会话,asp.net-mvc,nhibernate,ninject,Asp.net Mvc,Nhibernate,Ninject,使用: ASP.NET MVC3 Ninject 2 流畅的纤维酸盐 我有两个数据库(DB1和DB2)。我有一个基本存储库类(repository)和许多控制器(Controller1、Controller2) 公共MyController(IRepository someModelFromDB1Repository,IRepository someModelFromDB2Repository) { [...] } 公共类存储库:IRepository,其中T:Entity { 专用只读会话;

使用: ASP.NET MVC3 Ninject 2 流畅的纤维酸盐

我有两个数据库(DB1和DB2)。我有一个基本存储库类(repository)和许多控制器(Controller1、Controller2)

公共MyController(IRepository someModelFromDB1Repository,IRepository someModelFromDB2Repository)
{
[...]
}
公共类存储库:IRepository,其中T:Entity
{
专用只读会话;
公共存储库(ISessionFactory sessionFactory)
{
_session=sessionFactory.OpenSession();
}
}
公共类DB1会话工厂:ISessionFactory
{
私有只读NHibernate.ISessionFactory\u sessionFactory;
非公开会议;
公共DB1SessionFactory()
{
[...]
}
}
公共类DB2SessionFactory:ISessionFactory
{
私有只读NHibernate.ISessionFactory\u sessionFactory;
非公开会议;
公共DB2SessionFactory()
{
[...]
}
}
现在,当我创建MyController时。我希望注入我的存储库,但该存储库应该使用DB1(或DB2,取决于模型)SessionFactory

我想不出如何正确地将其全部注入。。。当我只有一个SessionFactory(DB1)时,这里是我与NINJECT的关系:

kernel.Bind<ISessionFactory>().To<DB1SessionFactory>()
            .InRequestScope();

kernel.Bind(typeof(IRepository<>)).To(typeof(Repository<>));
kernel.Bind()到()
.InRequestScope();
Bind(typeof(IRepository)).To(typeof(Repository));

编辑:


最好是根据模型在存储库中注入正确的会话。由于一些模型来自DB1,而另一些来自DB2,因此选择应该依赖于它。如果控制器/视图开发人员不必为任何事情操心(比如在存储库前面有[Named]),但如果这是必要的,那也太好了。即使使用了[Named],我也不知道如何根据控制器中的[Named]存储库在存储库中注入正确的会话…

首先,您应该在singelton范围内定义会话工厂,并将会话置于请求范围内

请按如下方式进行配置:

.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();
.Bind().To().Named(“DB1”)
.InSingletonScope();
.Bind().To().Named(“DB2”)
.InSingletonScope();
私有bool IsOnDB(IRequest请求,字符串dbName)
{
var repositoryType=request.ParentRequest.Service;
var modelType=repositoryType.GetGenericArguments()[0];
var databaseName=this.GetDatabaseForModel(modelType);
返回databaseName==dbName;
}
.Bind()
.ToMethod(ctx=>ctx.Kernel.Get(“DB1”).OpenSession())
.When(r=>this.IsOnDb(r,“DB1”))
.InRequestScope();
.Bind()
.ToMethod(ctx=>ctx.Kernel.Get(“DB2”).OpenSession())
.When(r=>this.IsOnDb(r,“DB2”))
.InRequestScope();

这在很大程度上取决于何时采用哪个DB的标准。如果没有这些信息,几乎不可能给你一个好的答案,因为有很多方法可以解决这个问题。这最终取决于模型。一些模型在一个数据库中,其他模型在另一个数据库中。如果对控制器/视图开发人员隐藏该逻辑会更好,但我找不到使其工作的方法。在控制器构造函数中,我有一些ModelDB1Repository和一些其他ModelDB2Repository,我希望它们都有一个带有正确会话的存储库。谢谢,聪明人!它工作得很好。我遇到的唯一问题是,当我将会话设置为InRequestScope时,在我的存储库有机会大部分时间使用它之前,会话就被关闭了……那么你应该考虑一下你的架构。在web请求结束时,应完成所有数据库请求。不要长时间使用会话,例如web会话。如果我想在web请求中重用同一会话(同一数据库的不同存储库中的同一会话)。会话是否需要存储在SessionProvider中,因为它声明为“InRequestScope”?否。这将导致错误的结果,因为会话提供程序是单例的,并且您将为不同的web请求重用会话。在这种情况下,你会有非常奇怪的行为。让Ninject决定谁获得哪个会话,而不是会话提供程序。您甚至不需要实现自己的会话工厂,只需使用两个正确配置的NHibernate会话工厂实例即可。
.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();