【问题标题】:Sharing Singleton dbContext across Repositories using Ninject使用 Ninject 跨存储库共享 Singleton dbContext
【发布时间】:2017-03-05 01:42:57
【问题描述】:

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

    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 作为参数传递)。

谢谢!

【问题讨论】:

    标签: asp.net-mvc repository ninject


    【解决方案1】:

    首先,要绑定一个单例,只需执行以下操作: kernel.Bind&lt;ItemDBEntities&gt;.To&lt;ItemDBEntities&gt;().InSingletonScope();

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

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

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

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

    【讨论】:

    • 非常感谢!我会试一试。可能我应该有一个 dbContext 容器,并将其作为一个单例,由所有存储库共享。此容器的 dbConext 最初设置为 null。当请求到来时,控制器构造函数将获取一个存储库,并创建 dbContext 以便所有存储库都可以访问它,因为容器是共享的。一旦请求结束,它将被销毁。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-24
    • 2019-05-15
    • 2023-02-06
    • 1970-01-01
    相关资源
    最近更新 更多