单元工作中有多个通用存储库?

Sha*_*ean 2 asp.net-mvc entity-framework unit-of-work repository-pattern

可以说我有2张桌子.ProductCategoryProduct.我有一个可以处理两个表的通用存储库:

public class GenericRepository<T> : IRepository<T>
Run Code Online (Sandbox Code Playgroud)

但是当使用工作单元模式时,我是否被迫为数据库中的所有表创建存储库?

public interface IUnitOfWork : IDisposable
{
    int SaveChanges();

    IRepository<ProductCategory> ProductCategoryRepository { get; }
    IRepository<Product> ProductRepository { get; }
}
Run Code Online (Sandbox Code Playgroud)

我没有办法将通用存储库添加到工作单元中吗?

Dmi*_*sev 5

您可以向IUnitOfWork接口添加通用方法:

public interface IUnitOfWork : IDisposable
{
    int SaveChanges();

    IRepository<T> Repository<T>();
}
Run Code Online (Sandbox Code Playgroud)

但我不推荐它.它有点像服务定位器反模式和SRP违规.更好的方法是从IUnitOfWork接口中删除所有存储库,因为提供对存储库的访问不是UnitOfWork的责任.我建议将存储库与UnitOfWork分开,并将它们自己注入消费者.

public class Consumer
{
    private readonly IUnitOfWork _unitOfWork;
    private readonly IRepository<Product> _products;

    public Consumer(IUnitOfWork unitOfWork, IRepository<Product> products)
    {
        _unitOfWork = unitOfWork;
        _products = products;
    }

    public void Action()
    {
        var product = _products.GetOne();

        product.Name = "new name";
        _products.Update(product);

        _unitOfWork.SaveChanges();
    }
}
Run Code Online (Sandbox Code Playgroud)

UDATE:

UnitOfWork和Repository可以共享上下文实例.这里是代码示例:

public class EfUnitOfWork : IUnitOfWork
{
    private readonly DbContext _context;

    public EfUnitOfWork(DbContext context)
    {
        _context = context;
    }

    public void SaveChanges()
    {
        _context.SaveChanges();
    }
}

public class EfRepository<T> : IRepository<T> where T : class
{
    private readonly DbContext _context;

    public EfRepository(DbContext context)
    {
        _context = context;
    }

    //... repository methods...
}

public class Program
{
    public static void Main()
    {
        //poor man's dependency injection
        var connectionString = "northwind";

        var context = new DbContext(connectionString);
        var unitOfWork = new EfUnitOfWork(context);
        var repository = new EfRepository<Product>(context);
        var consumer = new Consumer(unitOfWork, repository);
        consumer.Action();
    }
}
Run Code Online (Sandbox Code Playgroud)