【发布时间】:2010-11-27 08:58:34
【问题描述】:
我一直在探索 BDD/DDD,因此试图提出存储库模式的正确实现。到目前为止,很难就实现这一点的最佳方式达成共识。我试图将其归结为以下变体,但我不确定哪种方法最好。
作为参考,我正在构建一个以 NHibernate 作为后端的 ASP.MVC 应用程序。
public interface IRepository<T> {
// 1) Thin facade over LINQ
T GetById(int id);
void Add(T entity);
void Update(T entity);
void Remove(T entity);
IQueryable<T> Find();
// or possibly even
T Get(Expression<Func<T, bool>> query);
List<T> Find(Expression<Func<T, bool>> query);
}
public interface IRepository<T> {
// 2) Custom methods for each query
T GetById(int id);
void Add(T entity);
void Update(T entity);
void Remove(T entity);
IList<T> FindAll();
IList<T> FindBySku(string sku);
IList<T> FindByName(string name);
IList<T> FindByPrice(decimal price);
// ... and so on
}
public interface IRepository<T> {
// 3) Wrap NHibernate Criteria in Spec pattern
void Add(T entity);
void Update(T entity);
void Remove(T entity);
IList<T> FindAll();
IList<T> FindBySpec(ISpecification<T> specification);
T GetById(int id);
}
public interface IRepository<T> {
// 4) Expose NHibernate Criteria directly
T GetById(int id);
void Add(T entity);
void Update(T entity);
void Remove(T entity);
IList<T> FindAll();
IList<T> Find(ICriteria criteria);
// .. or possibly
IList<T> Find(HQL stuff);
}
我最初的想法是
1) 从效率的角度来看很好,但随着事情变得更加复杂,我可能会遇到麻烦。
2) 看起来很乏味,并且最终可能会导致一个非常拥挤的课程,但否则会在我喜欢的领域逻辑和数据层之间提供高度分离。
3) 预先编写查询似乎很困难,并且需要做更多的工作来编写查询,但将交叉污染限制在 Specs 层。
4) 我最不喜欢,但可能是最直接的实现,并且对于复杂的查询可能是最高效的数据库,尽管它给调用代码带来了很多责任。
【问题讨论】:
-
+1 及时提问。我也一直在为存储库模式而苦苦挣扎。
-
可能不是您想要的,但我发现 Spec 模式的这种实现非常酷:mathgeekcoder.blogspot.com/2008/07/…。主要是因为它可以让你使用 Linq2Sql/Linq2NHibernate/etc。
-
感谢 TrueWill 和 Martinho,这实际上与我最近发布的另一个主题非常相关 stackoverflow.com/questions/1408553/…
标签: c# domain-driven-design repository-pattern bdd