使用存储库模式,工作单元和Unity的实体框架

时间:2013-10-01 12:59:09

标签: entity-framework inversion-of-control unity-container repository-pattern unit-of-work

使用this examplethis implementation提供的组合我试图创建一个解决方案,将UnitOfWork类与各个存储库分离,因为它们违反了开放 - 封闭原则,因为每次添加新存储库时,都必须修改UnitOfWork类。我使用Unity作为IoC容器来连接依赖项。

我遇到的问题是,在使用Unity自动连接UnitOfWorkIDbContext和存储库(IEmployeeRepositoryICustomerRepository)时,将注入存储库UnitOfWork的单独实例,当然,这会破坏目的。我需要在存储库之间共享上下文,似乎我错过了这个难题的一部分 - 目前(参见服务层),实例化的UnitOfWork将与每个UnitOfWork不同。库。

如何使用Unity和依赖注入将IUnitOfWork注入服务层并将此实例化的共享 UnitOfWork类传递到相应的存储库?

这是我提出的(伪造的)解决方案:

存储库

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();
    }

}

1 个答案:

答案 0 :(得分:8)

我认为您正在寻找的是每个请求生命周期管理器,以便您在请求期间只获得一个UnitOfWork实例和一个DbContext实例。 Unity 3的Unity bootstrapper for ASP.NET MVC有一个PerRequestLifetimeManager,可以让你这样做。

如果您不使用ASP.NET,则可以使用PerResolveLifetimeManager。我见过的另一种方法是将HierarchicalLifetimeManager与子容器结合使用(这使得注册在子容器中成为单例)。

相关问题