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.
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.
Perhaps the AggregateRoot1 repository could call AggregateRoot2 repository when it's constructing the the AggregateRoot1 entity.
I don't think this invalidates ddd since the repositories are still in charge of getting/creating their own entities.
I considered this as well, but what if Aggregate2 has a reference to Aggregate3, and aggregate3 to another and so one. Potentially this could be a rather large object graph. What are the suggested strategies for these scenarioes?
True, I know you're not supposed to worry about implementation too much in DDD but at that point Id lazyload the aggregates if I thought the graph is too large.
Ok, so far so good. :-) But when I'm creating the relation between AggregateRoot1.Entity1 --> AggregateRoot2, should this be done through the AggregateRootRepository1.AddRoot2ToEntity1(root1, root2) or through AggregateRepository2.AddRoot2ToRoot1(root1, root2) or a more direct assignment: root2.Entity1.AddRoot2(root2)
Personally I'd say none of them. I'd assign it via this: "entity1.Entity2 = entity2" and then the repository should be able to detect this relationship and do what ever it needs to do (i.e. update the db colum if thats the underlying store)
Thank you TWith2Sugars, but I would really like to have some more feedback before I close this question. I appreciate your answers-