在将近一年之后,我开始了一个新的mvc项目,这次是版本4。我想知道以下存储库模式实现是否弊大于利。
public interface IRepository<T> where T : class
{
IEnumerable<T> GetAll();
IQueryable<T> Query(Expression<Func<T, bool>> filter);
void Add(T entity);
void Remove(T entity);
}
public interface IUnitOfWork
{
void Commit();
}
public interface IDbContext : IDisposable
{
IDbSet<T> Set<T>() where T : class;
int SaveChanges();
}
public class DbContextAdapter : IDbContext
{
private readonly DbContext _myRealContext;
public DbContextAdapter()
{
this._myRealContext = new EstafaContext();
}
public void Dispose()
{
_myRealContext.Dispose();
}
public IDbSet<T> Set<T>() where T : class
{
return _myRealContext.Set<T>();
}
public int SaveChanges()
{
return _myRealContext.SaveChanges();
}
}
public class SqlRepository<T> : IRepository<T> where T : class
{
private IDbSet<T> _dbSet;
public SqlRepository(IDbContext dbContext)
{
this._dbSet = dbContext.Set<T>();
}
public IEnumerable<T> GetAll()
{
return this._dbSet.ToList();
}
public IQueryable<T> Query(Expression<Func<T, bool>> filter)
{
return this._dbSet.Where(filter);
}
public void Add(T entity)
{
this._dbSet.Add(entity);
}
public void Remove(T entity)
{
this._dbSet.Remove(entity);
}
}
public class SqlUnitOfWork : IDisposable, IUnitOfWork
{
private IDbContext _dbContext;
private SqlRepository<Cliente> _clientes ;
public SqlUnitOfWork()
{
this._dbContext = new DbContextAdapter();
}
public void Dispose()
{
if (this._dbContext != null)
{
this._dbContext.Dispose();
}
GC.SuppressFinalize(this);
}
public IRepository<Cliente> Clientes
{
get { return _clientes ?? (_clientes = new SqlRepository<Cliente>(_dbContext)); }
}
public void Commit()
{
this._dbContext.SaveChanges();
}
}
这样,我可以通过SqlUnitOfWork从一个点管理所有存储库。
我在以前的项目中使用了此设计,效果很好,但我觉得效率不高,甚至可能是多余的。
值得添加这样的抽象层吗?
提前致谢!
最佳答案
尽管我的实现与您的实现不完全相同,但对我来说似乎很可靠。
我通常所做的唯一其他更改是为每个实体类型存储库定义特定的接口(interface),如下所示:
public interface IClienteRepository : IRepository<Cliente>
{
IEnumerable<Cliente> GetByName(string firstName);
// etc
}
这样,我仍然可以将所有存储库通用地用于CRUD操作,但是我也可以使用相同的存储库来抽象一些查询逻辑。存储库的用户只需要知道他们想要什么,而不必知道如何获取它。
当然,这有点麻烦,需要您对存储库进行具体实现以添加额外的功能,但它只是封装了查询逻辑,无论如何您都可以通过应用程序在其他地方拥有这些查询逻辑。