仅为实际需要的AGGREGATE根提供存储库 直接访问。
1。 是否应该通过那些需要直接访问的聚合根的存储库来检索和保存不需要直接访问的聚合根?
例如,如果我们有Customer
和Order
聚合根,如果由于某种原因我们不需要直接访问Order
AR,那么我只假设订单可以通过遍历Customer.Orders
属性?
2。
应该ICustomerRepository
何时检索订单?检索Customer
AR时(通过ICustomerRepository.GetCustomer
)或我们遍历Customer.GetOrders
属性?
3。
ICustomerRepository
本身应该检索订单还是应该将此责任委托给IOrderRepository
?如果是后者,那么一种选择是将IOrderRepository
注入ICustomerRepository
。但由于外部代码不应该知道IOrderRepository
甚至存在(如果外部代码知道它的存在,那么它也可能直接使用IOrderRepository
),那么ICustomerRepository
应该如何获得引用到IOrderREpository
?
更新
1
关于实现,如果使用像NHibernate这样的ORM, 不需要IOrderRepository。
a)你是说在使用ORM时,我们通常不需要实现存储库,因为ORM隐式提供它们?
b)我确实计划学习一种ORM技术(可能是EF),但是从很少有人看过ORM,似乎如果你想要从Persistence层完全分离Domain或Application层,那么这两层就不应该了不使用ORM表达式,这也意味着ORM表达式和POCO只应存在于Repository实现中?c)如果出现某种情况由于某种原因AR根没有直接访问权限(并且项目不使用ORM),那么你的答案是什么?
感谢
答案 0 :(得分:3)
我很难想到一个聚合不需要直接访问的例子。但是,我认为在撰写本文时(大约2003年),强调限制或消除聚合之间的可遍历对象引用并不像现在这样普遍。因此,Customer
聚合可能会引用Order
聚合的集合。在这种情况下,可能不需要直接引用Order
,因为来自Customer
的遍历是可接受的。
关于实现,如果使用像NHibernate这样的ORM,则不需要IOrderRepository
。 Order
聚合只会有一个映射。此外,Customer
的映射将指定更改应级联到相应的Order
聚合。
ICustomerRepository应该何时检索订单?
这个问题引起了对聚合之间的可遍历对象引用的关注。 ORM提供的解决方案是延迟加载,但是lazy loading can be problematic。理想情况下,只有在需要时才会检索客户的订单,这取决于上下文。因此,我的建议是避免聚合之间的可遍历引用,而是使用存储库搜索。
<强>更新强>
a)您仍然需要一些实现ICustomerRepository的东西,但是如果配置了映射,实现将非常简单 - 您将委托ORM的API来实现每个存储库方法。但是,不需要IOrderRepository。
b)对于完全封装,存储库接口不包含任何特定于ORM的内容。存储库实现将使存储库合同适应ORM细节。
c)很难对我无法描绘的场景做出判断,但似乎不需要订单存储库接口,您仍然可以拥有订单存储库以更好地分离责任。无需注入,只需让Customer repo实现创建Order repo的实例。