如何检索没有存储库的聚合根?

时间:2013-05-22 17:54:17

标签: domain-driven-design ddd-repositories aggregateroot

Eric Evan的DDD书,pg。 152:

  

仅为实际需要的AGGREGATE根提供存储库   直接访问。

1。 是否应该通过那些需要直接访问的聚合根的存储库来检索和保存不需要直接访问的聚合根?

例如,如果我们有CustomerOrder聚合根,如果由于某种原因我们不需要直接访问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),那么你的答案是什么?

感谢

1 个答案:

答案 0 :(得分:3)

我很难想到一个聚合不需要直接访问的例子。但是,我认为在撰写本文时(大约2003年),强调限制或消除聚合之间的可遍历对象引用并不像现在这样普遍。因此,Customer聚合可能会引用Order聚合的集合。在这种情况下,可能不需要直接引用Order,因为来自Customer的遍历是可接受的。

关于实现,如果使用像NHibernate这样的ORM,则不需要IOrderRepositoryOrder聚合只会有一个映射。此外,Customer的映射将指定更改应级联到相应的Order聚合。

  

ICustomerRepository应该何时检索订单?

这个问题引起了对聚合之间的可遍历对象引用的关注。 ORM提供的解决方案是延迟加载,但是lazy loading can be problematic。理想情况下,只有在需要时才会检索客户的订单,这取决于上下文。因此,我的建议是避免聚合之间的可遍历引用,而是使用存储库搜索。

<强>更新

a)您仍然需要一些实现ICustomerRepository的东西,但是如果配置了映射,实现将非常简单 - 您将委托ORM的API来实现每个存储库方法。但是,不需要IOrderRepository。

b)对于完全封装,存储库接口不包含任何特定于ORM的内容。存储库实现将使存储库合同适应ORM细节。

c)很难对我无法描绘的场景做出判断,但似乎不需要订单存储库接口,您仍然可以拥有订单存储库以更好地分离责任。无需注入,只需让Customer repo实现创建Order repo的实例。