使用存储库模式,工作单元和统一性的实体框架 [英] Entity Framework using Repository Pattern, Unit of Work and Unity
问题描述
使用此示例和此实现我正在尝试创建一个解决方案,以将 UnitOfWork
类与单个存储库,因为它们违反了开放式封闭原则,因为每次添加新存储库时,都必须修改 UnitOfWork
类。我正在使用Unity作为IoC容器来连接依赖项。
Using a combination provided from this example and this implementation I am trying to create a solution that decouples the UnitOfWork
class from the individual repositories, as they violate the Open-Closed Principle, since every time you added a new repository you would have to modify the UnitOfWork
class. I am using Unity as the IoC container to wire up dependencies.
我的问题是自动连接 UnitOfWork
, IDbContext
和存储库( IEmployeeRepository
和 ICustomerRepository
)使用Unity,存储库将被注入 UnitOfWork
的单独实例,这当然会破坏目的。我需要在整个存储库中共享上下文,并且似乎这个谜题缺少了一部分-此刻(请参见服务层)实例化的 UnitOfWork
将不同于每个存储库的 UnitOfWork
。
The problem I have is that in automatically wiring up the UnitOfWork
, IDbContext
and the repositories (IEmployeeRepository
and ICustomerRepository
) using Unity, the repositories will be injected with separate instances of the UnitOfWork
, which, of course, defeats the purpose. I need to share the context across the repositories, and it seems I am missing a piece to this puzzle - at the moment (see Service layer) the UnitOfWork
instantiated will be different to the UnitOfWork
for each of repositories.
如何将 IUnitOfWork
注入服务层并传递此实例化的 shared <使用统一和依赖注入将code> UnitOfWork 类分配到各自的存储库?
How do inject the IUnitOfWork
into the service layer and pass this instantiated shared UnitOfWork
class to the respective repositories, using Unity and dependency injection?
这是我建议的(预制)解决方案:
Here's my proposed (fabricated) solution:
存储库
public interface IRepository<TEntity> where TEntity : class
{
TEntity Create();
// omitted for brevity
}
public class Repository<TEntity> : IRepository<TEntity>
where TEntity : class
{
private readonly DbContext _context;
public Repository(IUnitOfWork uow)
{
_context = uow.Context;
}
public virtual TEntity Create(TEntity entity)
{
return _context.Set<TEntity>().Add(entity);
}
// omitted for brevity
}
public interface IEmployeeRepository : IRepository<Employee>
{
}
public interface ICustomerRepository : IRepository<Customer>
{
}
public class EmployeeRepository : Repository<Employee>
{
public EmployeeRepository(IUnitOfWork uow)
: base(uow)
{
}
}
public class CustomerRepository : Repository<Customer>
{
public CustomerRepository(IUnitOfWork uow)
: base(uow)
{
}
}
DbContext Factory
public interface IDbContextFactory
{
DbContext GetContext();
}
public class DbContextFactory : IDbContextFactory
{
private readonly DbContext _context;
public DbContextFactory()
{
_context = new MyDbContext("ConnectionStringName");
}
public DbContext GetContext()
{
return _context;
}
}
工作单位
public interface IUnitOfWork
{
void SaveChanges();
DbContext Context { get; }
}
public class UnitOfWork : IUnitOfWork, IDisposable
{
private readonly DbContext _context;
private bool disposed = false;
public UnitOfWork(IDbContextFactory contextFactory)
{
_context = contextFactory.GetContext();
}
public void SaveChanges()
{
if (_context != null)
{
_context.SaveChanges();
}
}
public DbContext Context
{
get { return _context; }
}
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
{
_context.Dispose();
}
}
disposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
服务
public class CompanyService
{
private readonly IUnitOfWork _uow;
private readonly IEmployeeRepository _employeeRepository;
private readonly ICustomerRepository _customerRepository;
public CompanyService(IUnitOfWork uow, IEmployeeRepository employeeRepository, ICustomerRepository customerRepository)
{
_uow = uow;
_employeeRepository = employeeRepository;
_customerRepository = customerRepository;
}
// over-simplified example method
public void AddEmployeeAndCustomer()
{
_employeeRepository.Create(new Employee {Id = 1, Name = "Test Employee"});
_customerRepository.Create(new Customer { Id = 2, Name = "Test Customer" });
_uow.SaveChanges();
}
}
推荐答案
我认为您正在寻找的是每个请求生命周期管理器,因此在请求期间您只能获得一个UnitOfWork实例和一个DbContext实例。 Unity 3具有 ASP.NET MVC的Unity引导程序,其中具有 PerRequestLifetimeManager ,您可以执行此操作。
I think what you are looking for is a per request lifetime manager so that you only get one UnitOfWork instance and one DbContext instance for the duration of a request. Unity 3 has the Unity bootstrapper for ASP.NET MVC which has a PerRequestLifetimeManager which lets you do this.
如果您不使用ASP.NET,则可以使用PerResolveLifetimeManager。我见过的另一种方法是将HierarchicalLifetimeManager与子容器结合使用(使注册在子容器中成为单例)。
If you are not using ASP.NET then you could probably use a PerResolveLifetimeManager. Another approach I've seen is a HierarchicalLifetimeManager combined with a child container (which makes the registrations a singleton within the child container).
这篇关于使用存储库模式,工作单元和统一性的实体框架的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!