Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Aggregate Root references other aggregate roots

I'm currently working a lot with DDD, and I'm facing a problem when loading/operating on aggregate roots from other aggregate roots.

For each aggregate root in my model, I also have a repository. The repository is responsible for handling persistence operations for the root.

Let's say that I have two aggregate roots, with some members (entities and value objects).

AggregateRoot1 and AggregateRoot2.

AggregateRoot1 has an entity member which references AggregateRoot2.

  1. When I load AggregateRoot1, should I load AggregateRoot2 as well?
  2. Should the repository for AggregateRoot2 be responsible for this?
  3. If so, is it okay for the entity in AggregateRoot1 to call the repository of AggregateRoot2 for loading?

Also, when I create an association between the entity in AggregateRoot1 to AggregateRoot2, should that be done through the entity, or through the repository for AggregateRoot2?

Hope my question makes sense.

[EDIT]

CURRENT SOLUTION

With help from Twith2Sugars I've come up with the following solution:

As described in the question, an aggregate root can have children that have references to other roots. When assigning root2 to one of the members of root1, the repository for root1 will be responsible for detecting this change, and delegating this to the repository for root2.

public void SomeMethod() {     AggregateRoot1 root1 = AggregateRoot1Repository.GetById("someIdentification");     root1.EntityMember1.AggregateRoot2 = new AggregateRoot2();     AggregateRoot1Repository.Update(root1); }  public class AggregateRoot1Repository {     public static void Update(AggregateRoot1 root1)     {         //Implement some mechanism to detect changes to referenced roots         AggregateRoot2Repository.HandleReference(root1.EntityMember1, root1.EntityMember1.AggregateRoot2)     } } 

This is just a simple example, no Law of Demeter or other best principles/practices included :-)

Further comments appreciated.

like image 532
tschmuck Avatar asked Feb 07 '11 09:02

tschmuck


People also ask

Can an aggregate root reference another aggregate root?

What you cannot do is reference anything inside the other aggregate root.

Can aggregate contain other aggregates?

[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.

What is aggregate and aggregate root?

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.

How do you choose the aggregate root?

When choosing an aggregate root you choose between Transactional Consistency and Eventual Consistency. When your business rules allow you would rather favour Eventual Consistency.


1 Answers

I've been in this situation myself and came to a conclusion that it's too much of a head ache to make child aggregates work in an elegant way. Instead, I'd consider whether you actually need to reference the second aggregate as child of the first. It makes life much easier if you just keep a reference of the aggregate's ID rather than the actual aggregate itself. Then, if there is domain logic that involves both aggregates this can be extracted to a domain service and look something like this:

public class DomainService {     private readonly IAggregate1Repository _aggregate1Repository;     private readonly IAggregate2Repository _aggregate2Repository;      public void DoSomething(Guid aggregateID)     {         Aggregate1 agg1 = _aggregate1Repository.Get(aggregateID);         Aggregate2 agg2 = _aggregate2Repository.Get(agg1.Aggregate2ID);          agg1.DoSomething(agg2);     } } 

EDIT:

I REALLY recommend these articles on the subject: https://vaughnvernon.co/?p=838

like image 150
David Masters Avatar answered Sep 21 '22 10:09

David Masters