如果你有一个业务规则,用户(或用户界面)永远不会看到表中的前30个项,你应该把这个过滤器放在Repository的GetAll()中吗?这意味着,存储库是否会处理数据过滤,将数据模型化为像ViewModel或Controller一样交给调用者?我听说模型应该很厚,控制器/ vms应该很轻。
我遇到的问题是另一个与我共享项目的开发人员,他的所有存储库(每个表一个)都使用相同的实现,只是将LinqToSql类型的属性复制到域类型。除了通过提供的Func更新和删除或获取数据之外,存储库本身没有逻辑。
另一方面,我为每个表创建了一个存储库(继承自T的IRepository),并将特定逻辑放在一些(不是全部)我认为需要逻辑来交还域对象的地方。所以在我的情况下,业务逻辑可以在存储库中完成,在他的情况下,它必须由用户完成,可以是服务或直接ViewModel。哪个更优选?
答案 0 :(得分:6)
如果你有一个业务规则,用户(或用户界面)永远不会看到表中的前30个项目,你应该把这个过滤器放在Repository的GetAll()中吗?
首先,这听起来不像是商业规则。业务规则以ubiquitous language表示,除非您正在使用数据库引擎,否则此语言不包含“table”之类的字。
回答你的主要问题,过滤逻辑绝对可以存在于存储库中。这就是repository的用途:封装存储,检索和搜索。关于存储库最重要的一点是它的接口属于域层,但其实现属于数据访问层。所以在你的情况下代码看起来像这样:
域:
// repository interface:
public interface Orders{
IList<Order> GetDelinquent();
}
数据访问:
public SqlOrders : Orders{
IList<Order> GetDelinquent(){
// do whatever needs to be done to find
// delinquent orders in sql database.
// filter first 30 records for example
}
}
请注意,存储库界面会将域置于焦点(我们不会说'除了前30条记录以外的所有',我们说'拖欠')。
我遇到的问题是另一个与我共享项目的开发人员,他的所有存储库(每个表一个)都使用相同的实现,只是将LinqToSql类型的属性复制到域类型。除了通过提供的Func更新和删除或获取数据之外,存储库本身没有逻辑。
另一方面,我为每个表创建了一个存储库(继承自T的IRepository),并将特定逻辑放在一些(不是全部)我认为需要逻辑来交还域对象的地方。
通用存储库界面通常是一个坏主意,它太以数据为中心,太过于CRUDy,请参阅this answer了解详细信息和链接。
所以在我的情况下,业务逻辑可以在存储库中完成,在他的情况下,它必须由用户完成,可以是服务或直接ViewModel。哪个更优选?
业务逻辑和数据访问逻辑之间存在很大差异。您希望避免将业务逻辑放入存储库实现中。此逻辑属于域对象。