我一直在开发一个应用程序,我正在尝试使用DDD和其他工具(Nhibernate和asp.net MVC)。
在这个应用程序中,我们需要在存储库的Person实体中通过Name实现“搜索”。所以,我们有一个存储库库(RepositoryBase类),在这个实现中我有一个适用于这个项目的通用方法。
public IEnumerable<T> FindAll(Expression<Func<T, bool>> condition) {
return Session.QueryOver<T>().Where(condition);
}
在我的asp.net mvc应用程序中,我们可以使用它:
var list = _repositoryPerson.FindAll(x => x.Name == "Felipe");
另一方面,我们可以为此任务创建一个特定的方法(在RepositroyPerson类中),如:
public IEnumerable<Person> FindByName(string name) {
return Session.QueryOver<Person>().Where(x => x.Name == name);
}
在我的asp.net mvc应用程序中,我们可以使用它:
var list = _repositoryPerson.FindByName("Felipe");
我的问题是:
1 - 根据DDD满足此要求的推荐方法是什么?具体还是基类?
2 - 有人推荐使用Nhibernate QueryOver实现一些很好的Repository库(泛型)实现吗?
如果有人可以帮助我,我会非常感激! 感谢
更新
如果我需要,例如,复杂的搜索,例如组合条件......例如:名称(可选)和年龄(可选)和城市(可选)和其他字段....每个字段都是可选的并且组合与其他领域!建议使用表达式还是不建议?你会如何实现这个代码?
PS:对不起我的英文!
由于
答案 0 :(得分:4)
为了充分利用这两个方面,您可以像在基类中一样实施FindByName
方法,将其标记为protected
或protected internal
(取决于是否您希望允许其他程序集定义Repository实现),然后从您的特定存储库对象中调用它。
protected internal IEnumerable<T> FindAll(Expression<Func<T, bool>> condition) {
return Session.QueryOver<T>().Where(condition);
}
public IEnumerable<Person> FindByName(string name) {
return base.FindAll(x => x.Name == name);
}
这将允许您为将要使用该方法的案例编写特定测试,同时还允许您更改ORM实现,而无需在大量位置更改它。
更新: 为了在FindAll中组合多个条件,您可以使用Aggregate简单地组合它们(我没有用NHibernate测试它,但如果它中断了,你可以用foreach替换它)。
public IEnumerable<T> FindAll(IEnumerable<Expression<Func<T, bool>>> conditions)
{
return conditions.Aggregate(Session.QueryOver<T>(), (current, condition) => current.Where(condition)).List();
}
然后方法可以使用可选参数,并创建传递给FindAll的条件列表。
public IEnumerable<T> FindByParams(string name=null, string city=null)
{
var wheres = new List<Expression<Func<T, bool>>>();
if (name != null)
{
wheres.Add(x => x.Name == name);
}
if (city != null)
{
wheres.Add(x => x.City == city);
}
return base.FindAll(wheres);
}
答案 1 :(得分:1)
两种方法都可以使用泛型方法,但是findmyname可以为您提供更好,更干净的代码。 我认为这是一个品味问题,你想成为DDD的纯粹主义者。我将为更复杂的要求创建特定方法,例如搜索或其他东西,但保持简单是我的选择
答案 2 :(得分:1)
我同意奥斯卡 - 我更喜欢特定的方法,主要原因是它们更容易被测试。围绕IQueryable和Expression对象构建合理的测试非常具有挑战性。
答案 3 :(得分:1)
其他注意事项:
您的存储库代码的消费者是谁?如果您将您的存储库暴露给可能会挣扎或滥用更抽象的接口的gui或其他开发人员,那么还有额外的动机来提供更清晰的特定接口。
界面多么臃肿?仅仅因为表达式几乎可以并不意味着它通常是。但是在那些情况下,可能是因为你可以像在更新中那样组合搜索条件,然后再倾向于使用更抽象的方法,至少作为帮助者。
我个人赞成尽可能使用更具体的界面
干杯,
Berryl