2017-03-05 36 views
0

我阅读了一些关于类似主题的文章。我有一个部分仓库使用Ninject跨资料库共享Singleton dbContext

public class EFPartRepository : IPartRepository 
    { 
     private ItemDBEntities dbContext = null; 
     public EFPartRepository(ItemDBEntities dbContext) 
     { 
      this.dbContext = dbContext; 
     } 
    } 

我会用另一个仓库命名的图像库

public class EFUploadedImageRepository : IUploadedImageRepository 
{ 
    private ItemDBEntities dbContext = null; 
    public EFUploadedImageRepository(ItemDBEntities dbContext) 
    { 
     this.dbContext = dbContext; 
    } 
} 

因为他们将在同一请求中使用,我希望他们的请求期间共享的DbContext的单,所以不会有任何异常“一个实体对象不能被IEntityChangeTracker的多个实例引用”

这是我原来的Ninject注册码。

private static void RegisterServices(IKernel kernel) 
    { 
     kernel.Bind<IPartRepository>().To<EFPartRepository>(); 
     kernel.Bind<IUploadedImageRepository>().To<EFUploadedImageRepository>(); 
    } 

所以我的问题是,这里是初始化这个单身的最佳场所,所以它可以通过不同的全球资源库很容易使用?以及如何申报? (最糟糕的情况是在每次调用期间总是传递dbContext作为参数)。

谢谢!

回答

1

首先,以一个单绑定,简单地做: kernel.Bind<ItemDBEntities>.To<ItemDBEntities>().InSingletonScope();

然而,你可能要考虑这个问题。 definiton的SingletonScope只要内核存活就会存活。因此,除非您在应用程序生命周期的某个位置重新创建内核,否则基础数据库连接将在整个生命周期内保持打开状态。 任何SQL实现将具有有限的(即使非常大的)可用连接数量(通常受到可用的TCP套接字数量的限制)。这意味着,如果您的应用程序的许多副本正在运行,则无法再运行。

此外,这种方法将迫使连接长期居住。这将如何恢复?如果在一个存储库中引发异常,导致单例数据库上下文具有损坏状态会怎么样?

更经常的方法是设置一个存储库,并在解析范围内创建一个上下文。

如果您想共享一个底层上下文,然后创建一个IMyDBContext,将其注册到解析范围(例如对于web-> request范围),然后注入这两个存储库。它们将具有相同的上下文,实体可以在两者之间共享,但是会为每个分辨率重新创建连接。

+0

非常感谢!我会试一试。也许我应该有一个dbContext容器,并将其作为一个单例,由所有存储库共享。该容器最初将dbConext设置为null。当请求到达时,控制器构造函数将获得一个存储库,并创建dbContext,以便所有存储库都可以访问它,因为容器是共享的。一旦请求结束,它就会被销毁。 – Chris

+0

@Chris正确。 – zaitsman