使用基于基础具体类的多个存储库

时间:2013-09-11 17:30:22

标签: c# repository-pattern unit-of-work

我发现在我的UnitOfWork中,我有一个每种类型实体的存储库,而且我没有使用聚合根,所以我正在尝试解决这个问题。解决计算机库存的问题,我目前的UnitOfWork结构如此:

public class UnitOfWork : IUnitOfWork
{
    private readonly ReportingDbContext _dbContext = null;

    public UnitOfWork()
    {
        _dbContext = new ReportingDbContext();
    }

    public void Commit()
    {
        _dbContext.SaveChanges();
    }

    // Inventory
    public IRepository<ComputerEntity> Computers {get { return new Repository<ComputerEntity>(_dbContext); }}
    public IRepository<NetworkAdapterEntity> NetworkAdapters { get { return new Repository<NetworkAdapterEntity>(_dbContext); } }
    // plus a bunch more
}

我只希望我的聚合根出现在那里,这应该很容易做到。我认为问题是我正在使用单个存储库类并在我新建它时输入类型。我相信答案是拥有多个存储库,每个存储库对应一个聚合根。我正在为每种类型使用的这个通用存储库的好处是,它处理我的所有实体框架内容,例如通过ID查找,保存到DbSet等。我的通用存储库是这样设置的:

public class Repository<T> : IRepository<T> where T : class
{
    protected DbContext DbContext { get; set; }
    protected DbSet<T> DbSet { get; set; }

    public Repository(DbContext dbContext)
    {
        if (dbContext == null)
        {
            throw new ArgumentNullException("dbContext");
        }
        DbContext = dbContext;
        DbSet = DbContext.Set<T>();
    }

    public IQueryable<T> GetAll()
    {
        return DbSet;
    }

    public IQueryable<T> Find(System.Linq.Expressions.Expression<Func<T, bool>> predicate)
    {
        return DbSet.Where(predicate);
    }

    // the rest of the implementation omitted for brevity
}

此存储库使用的接口可以使用我尚未创建的聚合根存储库:

public interface IRepository<T> where T : class
{
    IQueryable<T> GetAll();
    IQueryable<T> Find(Expression<Func<T, bool>> predicate);
    T GetById(int id);
    void Remove(T entity);
    void Add(T newEntity);
}

现在,这是问题的真正含义。我在我的具体Repository类中很好地实现了上面的接口,并且我希望在我将要制作的所有聚合根存储库中具有相同的功能。我不想直接使用这个通用存储库,因为我只是想用它来获取它与Entity Framework一起使用的基本CRUD内容。我不想重复已经实现的通用存储库的东西,只是继承它。更重要的是,我想第一次正确设计。

是否适合创建我的基于聚合根的存储库:

public interface IComputerRepository
{
    string ComputerSpecificMethod(string param);  
}

public class ComputerRepository : Repository<ComputerEntity>, IComputerRepository
{
    public ComputerRepository(DbContext dbContext) : base(dbContext)
    {
        // 
    }

    public string ComputerSpecificMethod(string param)
    {
        // do stuff
        return "test";
    }
}

然后在我的UnitOfWork中使用这个新的花式存储库(以及其他类似的存储库):

public IRepository<ComputerEntity> Computers {get { return new ComputerRepository(_dbContext); }}

而不是:

public IRepository<ComputerEntity> Computers {get { return new Repository<ComputerEntity>(_dbContext); }}

目标是坚持UnitOfWork / Repository模式,我不确定这是否是正确的方法。

1 个答案:

答案 0 :(得分:0)

我发现这样做对我有用的方法是在我的工作单元类中为每个自定义存储库提供接口:

    public IInventoryRepository Computers { get { return new InventoryRepository(_dbContext); } }

当然,它在自己的课程中实现。为了让它继承正确,我这样做了:

public class InventoryRepository : GenericRepository<ComputerEntity>, IInventoryRepository
{


    public InventoryRepository(DbContext dbContext) : base(dbContext)
    {

    }

  // your custom methods go here
 }

然后我可以在我的WCF服务中使用它:

 using (var uoW = new UnitOfWork())
        {
            var repo = uoW.Computers;
            var computerEntity = repo.FindComputerByHostname(hostname, client);
            // do more stuff
        }