I've recently been delving into DDD resources (books--Vaughn Vernon's--and other online resources) and in my attempt to do two things at once (work on a pet project and apply what I've been learning) I found myself stuck at a point where I have to make a decision about how aggregates and entities are created, while maintaining invariants and not break the rule about transactional consistency for one aggregate at a time.
In my domain I can have an aggregate root that we can call
Container, which contains some metadata properties and a list of ids for referencing another aggregate, let's call this one 'Document'. Both of these will be editable independently of eachother, so it makes sense to have them as separate aggregates. To change the
Document I don't have to update the
Container and vice-versa.
For me, an empty
Container does not make sense. When you create it, there needs to be at least one
Document in it. I was thinking of providing it by default.
Having this rule means that when I create a new
Container in order for it to be in a valid state, it needs at least one
Document id. To create a
Document you need to assign it its parent id, the
Container. So now I feel I have chicken and egg problem.
Things I've considered
I could get a new id from the
Container repository and create that child
Document with it as its parent, then create a
Container with the same id and pass the
Document id as a "child". This would be done within a DomainService method, which is what some recommend to maintain consistency between multiple aggregates. This feels like braking the rule of "one aggregate" at a time.
I could create a new
Container, publish an event that it was created, then a subscriber would create a "default"
Document and assign it to the
Container. This seems like a good way of doing it, but if the second event is not properly handed I end up with an empty/invalid-state `Container.
Do I treat the
Container as a kind of a tag and not make it an aggregate? basically flipping the whole thing over? A
Document then would be center stage, so when I create a
Document I need to assign/create a
ContainerId (tag)... Listing would then be a bit more cumbersome, since you'd have to keep track of all
ContainerId form all
To make matters worse, a
Document can have referential ids for other entities (I'm still deciding if it's worth making those value objects, even though it feels to me like they have life-cycle--can get updated over time), which also has this rule of "at least one".
Any suggestions? Am I modelling this wrong? Are my concerns valid, but shouldn't pose a problem in this particular case? Any help would be much appreciated!
I have so many questions! but I'll stop here.