我正在学习存储库模式,我发现了许多代码示例,但几乎都是相同的,所以我对这方面有疑问,例如这个设计:
public interface IRepository<T>
{
void Add(T entity);
void Update(T entity);
void Delete(T entity);
IList<T> GetAll();
}
public interface IPostRepository
{
int GetComentCount();
}
public class EFRepository<T>: IRepository<T>
{
public void Add(T entity){ /*implementation...*/ }
public void Update(T entity){ /*implementation...*/ }
public void Delete(T entity){ /*implementation...*/ }
public IList<T> GetAll(){ /*implementation...*/ }
}
public class PostRepository: EFRepository<Post>, IPostRepository
{
public int GetComentCount(){ /*implementation...*/ }
}
public class UnitOfWork: IUnitOfWork, IDisposable
{
IPostRepository PostRepository {get;}
}
我可以这样做:
IUnitOfWork UoW = new UnitOfWork();
int nComments = UoW.PostRepository.GetComentCount();
但不是这样:(显然)
var collection = UoW.PostRepository.GetAll();
我该怎么办?我必须在UoW中创建另一个属性并返回一个IRepository吗? 我必须为没有CRUD操作的每个存储库创建一个接口(例如IPostRepository)吗?具体的存储库是否必须一次从EFRepository类和接口继承(例如:类PostRepository:EFRepository,IPostRepository {})?
您怎么看?
PD:请原谅我可怜的英语。答案 0 :(得分:1)
如果您将IPostRepository更改为从IRepository继承,则只需扩展接口表面,因此您无需重新定义所有方法。
例如,通过此更改:
public interface IRepository<T>
{
void Add(T entity);
void Update(T entity);
void Delete(T entity);
IList<T> GetAll();
}
public interface IPostRepository : IRepository<int>
{
int GetComentCount();
}
public class EFRepository<T> : IRepository<T>
{
public void Add(T entity) { Console.WriteLine("Works"); }
public void Update(T entity) { /*implementation...*/ }
public void Delete(T entity) { /*implementation...*/ }
public IList<T> GetAll() { return null; }
}
public class PostRepository : EFRepository<int>, IPostRepository
{
public int GetComentCount() { return 0; }
}
public interface IUnitOfWork
{
}
public class UnitOfWork : IUnitOfWork, IDisposable
{
public IPostRepository PostRepository { get { return new PostRepository(); } }
public void Dispose()
{
throw new NotImplementedException();
}
}
以下代码将打印工作:
UnitOfWork t = new UnitOfWork();
t.PostRepository.Add(1);
基本上,您的PostRepository不需要重新实现Add / Update / Delete方法,因为该接口契约已存在于基类EFRepository中并将被使用。 IPostRepository将强制您仅提供扩展接口合同。
至于最佳做法,我认为没有一个好的解决方案。我尝试使用继承方法,但我已经看到了具有ReadOnly / Add / AddUpdate / etc的良好生产代码。组合的存储库接口。
P.S。我在示例中使用 int 更改了 Post 类,以避免定义一个全新的类。