I have a few objects that represent a web application. Currently I have a cluster object to represent a specific deployment of the app. Within a cluster object I have the following objects: Server, Customer, User. None of these objects can exist without being part of a cluster, so I created a ClusterRepository to retrieve the clusters from the database. Now, from the cluster I need to get a list of Customers, presumably by using a method in the Cluster object like GetCustomers(). Now, my initial thought was to then offload the work of this operation to a CustomerRepository, but since repositories are only for aggregate roots, where should the data access logic go? Does this belong in a service class?
[Evans] states that one Aggregate may hold references to the Root of other Aggregates. However, we must keep in mind that this does not place the referenced Aggregate inside the consistency boundary of the one referencing it. The reference does not cause the formation of just one whole Aggregate.
Aggregate is a pattern in Domain-Driven Design. A DDD aggregate is a cluster of domain objects that can be treated as a single unit. An example may be an order and its line-items, these will be separate objects, but it's useful to treat the order (together with its line items) as a single aggregate.
An AGGREGATE is a cluster of associated objects that we treat as a unit for the purpose of data changes. Each AGGREGATE has a root and a boundary. The boundary defines what is inside the AGGREGATE. The root is a single, specific ENTITY contained in the AGGREGATE.
A single Bounded Context can include many aggregate roots, or we can organise a single aggregate root into a single Bounded Context. An Order aggregate root, consists of entities such as OrderLine, Customer and Product, and value objects such as ShippingAdress, PaymentMethod etc.
Essentially, an Aggregate root is any object that you might need to fetch as the root of an object graph. Just because a specific entity is an aggregate root, and has a repository, does not mean that another entity which is one of it's properties can't also be an aggregate root - with it's own repository.
A good example is a customer billing system. Customer would certainly be an aggregate root, and would contain a collection of invoices... But for another application function, the invoice itself might be an aggregate root with constituent LineItem objects in it's object graph.
So in your example, there is nothing wrong with creating another repository for customers, if you need to fetch them independantly of clusters in some situations.
NOTE: See thread in comments as well. Although root entities can, (and often will) have references to other root entities, it is frowned upon (and that may be too mild a turn of phrase) to allow the repository for any root entity to contain functionality that manages (creates, updates, or deletes) any root entity within its object graph that it has a reference to. Any such referenced root entities should have their own individual repositories, and the functionality to manage them (Create, Update and/or delete operations) should be in their repository, so that it is only in one place.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With