I'm hard-pressed to think of an example where an aggregate does not require direct access. However, I think at the time of writing (circa 2003), the emphasis on limiting or eliminating traversable object references between aggregates wasn't as prevalent as it is today. Therefore, it could have been the case that a Customer
aggregate would reference a collection of Order
aggregates. In this scenario, there may be no need to reference an Order
directly because traversal from Customer
is acceptable.
With regards to implementation, if done with an ORM like NHibernate, there is no need for an IOrderRepository
. The Order
aggregate would simply have a mapping. Additionally, the mapping for Customer
would specify that changes should cascade down to corresponding Order
aggregates.
When should ICustomerRepository retrieve orders?
This is the question which raises concern over traversable object references between aggregates. A solution provided by ORM is lazy loading, but lazy loading can be problematic. Ideally, a customer's orders would only be retrieved when needed and this depends on context. My suggestion, therefore, is to avoid traversable references between aggregates and use a repository search instead.
UPDATE
a) You would still need something that implements ICustomerRepository, but the implementation would be largely trivial if the mappings are configured - you'd delegate to the ORM's API to implement each repository method. No need for a IOrderRepository however.
b) For full encapsulation, the repository interface would not contain anything ORM-specific. The repository implementation would adapt the repository contract to ORM specifics.
c) Hard to make a judgement on a scenario I can't picture, but it would seem there is no need for Order repository interface, you can still have an Order Repository to better separate responsibilities. No need for injection either, just have the Customer repo implementation create an instance of Order repo.