使用存储库模式,工作单元和统一性的实体框架 [英] 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆