我阅读了一些有关类似主题的帖子。我有一个零件库
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作为参数传递)。
谢谢!
答案 0 :(得分:1)
首先,要绑定单例,只需执行以下操作:
kernel.Bind<ItemDBEntities>.To<ItemDBEntities>().InSingletonScope();
但是,您可能需要考虑这一点的含义。
根据定义,SingletonScope
将与内核生活一样长寿。因此,除非您在应用程序的生命周期中的某个位置重新创建内核,否则底层数据库连接将在整个生命周期内保持打开状态。
任何SQL实现都将具有有限(甚至非常大)的可用连接数(通常受可用TCP套接字数量的限制)。这意味着如果您的应用程序的许多副本正在运行,则无法再运行。
此外,这种方法将迫使连接长寿。这将如何恢复?如果在一个存储库中抛出异常导致单例db上下文具有损坏状态该怎么办?
更常规的方法是设置一个存储库,其中包含要在解决范围内创建一次的上下文。
如果要共享基础上下文,请创建IMyDBContext
,在解决方案范围内注册(例如,对于web - &gt;请求范围),然后注入两个存储库。它们将具有相同的上下文,并且可以在两者之间共享实体,但是将为每个分辨率重新创建连接。