【发布时间】:2012-04-18 00:47:17
【问题描述】:
我正在使用以下 UnitOfWork 类,以便通过使用泛型获取我的实体的存储库。
public class UnitOfWork : IUnitOfWork
{
private readonly EfDbContext _context;
public UnitOfWork()
{
_context = new EfDbContext();
}
public IRepository<T> RepositoryFor<T>() where T : Entity
{
return new Repository<T>(_context);
}
public void Save()
{
_context.SaveChanges();
}
}
但是,我遇到了一些问题,我有两个单独的类为单个实体独立实例化 UnitOfWork,这意味着为该实体创建了两个存储库。当我尝试保存实体时,这会导致实体框架引发“IEntityChangeTracker 的多个实例无法引用实体对象”错误。
我认为我需要更严格地遵循此 post by Tom Dykstra 中“创建工作单元类”部分中描述的 UOW 模式,其中存储库存储在私有字段中如果存在则重用,如果为空则创建。我遇到的问题是我希望我的 UOW 继续使用泛型 - Repository<T> - 而不必为我在代码中拥有的所有实体类型声明私有存储库字段。
我如何能够存储给定类型的存储库已被实例化的事实并重新使用它而不是创建它的新实例?
--- 编辑:这里是修复---
使用 Ninject,我调整了我的绑定,通过指定 InRequestScope 仅实例化存储库和 UOW 的单个实例
kernel.Bind(typeof(IRepository<>)).To(typeof(Repository<>)).InRequestScope();
//kernel.Bind<IUnitOfWork>().To<UnitOfWork>().InRequestScope(); // Removed based on comment below
kernel.Bind(typeof(EfDbContext)).ToSelf().InRequestScope();
【问题讨论】:
-
Singleton,或工厂,如果已创建,则保留对存储库的引用,并提供引用或副本或该存储库
-
假设有时您想使用 Include() 进行特定查询,那么通用存储库将不够用。您可能需要有一个用于继承通用存储库的特定实体类型的存储库。
-
为了完美,您不应该在 IoC 容器中注册
Repository<>。它是工作单元的一部分,不应允许它以某种方式获取它,除非从 UoW 实例中获取。此外,您显式地实例化它而不是从容器中解析。所以,在容器中注册是没有意义的。 -
这是有道理的。我删除了存储库的绑定。谢谢!
标签: c# entity-framework unit-of-work