使用Ninject在存储库之间共享Singleton dbContext

时间:2017-03-05 01:42:58

标签: asp.net-mvc repository ninject

我阅读了一些有关类似主题的帖子。我有一个零件库

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

我将使用另一个名为image repository的存储库

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 个答案:

答案 0 :(得分:1)

首先,要绑定单例,只需执行以下操作: kernel.Bind<ItemDBEntities>.To<ItemDBEntities>().InSingletonScope();

但是,您可能需要考虑这一点的含义。 根据定义,SingletonScope将与内核生活一样长寿。因此,除非您在应用程序的生命周期中的某个位置重新创建内核,否则底层数据库连接将在整个生命周期内保持打开状态。 任何SQL实现都将具有有限(甚至非常大)的可用连接数(通常受可用TCP套接字数量的限制)。这意味着如果您的应用程序的许多副本正在运行,则无法再运行。

此外,这种方法将迫使连接长寿。这将如何恢复?如果在一个存储库中抛出异常导致单例db上下文具有损坏状态该怎么办?

更常规的方法是设置一个存储库,其中包含要在解决范围内创建一次的上下文。

如果要共享基础上下文,请创建IMyDBContext,在解决方案范围内注册(例如,对于web - &gt;请求范围),然后注入两个存储库。它们将具有相同的上下文,并且可以在两者之间共享实体,但是将为每个分辨率重新创建连接。