I am new to DDD, I have a Partner aggregate which has an User reference. The User object itself is another Aggregate.
Since not all users has to be referenced in the Partner object, the User object is an aggregate root. The Partner is an aggregate root as well.
First: Would my design be wrong with one aggregate root inside another?
Second: If the design is right, would it be a bad practice to use one Repository inside another to persiste the Partner? (UserRepository inside PartnerRepository)
Obs: I am not using any ORM framework.
I am new to DDD...
I'll be answering this from a DDD standpoint, not OOP (Object Oriented Programming).
First: Would my design be wrong with one aggregate root inside another?
It wouldn't follow the general guidelines of Domain-Driven Design. If you want to reference one aggregate root from another, you would reference it by id.
Second: If the design is right, would it be a bad practice to use one Repository inside another to persiste the Partner? (UserRepository inside PartnerRepository)
Again if following the guidelines of DDD, you wouldn't do this, you would persist each aggregate separately using separate repositories.
Here's a link to an article by Vaughn Vernon, possibly the second greatest figure in the field of DDD to explain better.
First: Would my design be wrong with one aggregate root inside another?
Yes.
AGGREGATE A cluster of associated objects that are treated as a unit for the purpose of data changes. External references are restricted to one member of the aggregate, designated as the root. A set of consistency rules applies within the aggregate's boundaries.
Eric Evans, Domain Driven Design
The problem your design faces is this: the Partner aggregate cannot protect its own invariant if the User aggregate is allowed to modify the same state independently.
When, in your design, you assert that X is an aggregate, you are making two claims
That's the aggregate boundary -- changes on the outside don't need to look inside, changes inside don't need to look outside.
Therefore, nesting aggregates is a contradiction.
Another way of expressing the same idea: if one aggregate root is inside another, then you have an aggregate (the Partner aggregate) which has two roots (the Partner entity, and the User entity), which is precisely the situation that the aggregate pattern is intended to avoid.
Possible remedies:
One is that the User entity really is part of the Partner aggregate. Every change to the user is supposed to be managed by the Partner. You move the User back into the partner aggregate, and prevent your implementation from accessing it except by issuing commands to the aggregate root.
Another is that the User entity isn't part of the Partner aggregate. Then you eliminate the direct reference in the Partner; that might mean eliminating the reference completely (if the business rules of Partner don't depend upon user at all), or having a reference to the User identifier, and business rules that check the identifier without following it (in other words, your rules might check that an id reference is null/not null, or is/is not a member of a collection). If you think about it, the Partner aggregate can't even tell if the User it is referencing exists.
A third is the discovery of a new entity in your model, that includes the part of User that the Partner aggregate actually uses for validation. This might be a snapshot of User state, or it might be a refactoring of User into multiple pieces.
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