Proper way of creating child entities with DDD
Interesting. DDD vs Repository / ORM navigation properties. I think the answer depends on whether you are dealing with one aggregate or two. Should CarsModel be part of CarsCompany aggregate, or perhaps its own aggregate?
Approach one is to make the problem go away. MikeSW hinted at this. If CarsCompany and CarsModel don't need to be part of the same aggregate then they should only reference each other by identity, navigation properties should not be visible in the Domain.
Approach two is to treat adding to a relationship the same way we treat fetching an aggregate - make the Application Services call a method from the repository, which is correct place for your ORM-specific concerns to be addressed. Such a method could populate both ends of the relationship.
So, what's most correct way of adding child entities with DDD?
The third approach is called Tight Coupling. Company
, Car
and Modification
know almost everything about each other.
The second approach is widely proposed in DDD. An domain object is responsible for creating a nested domain object AND registering it inside.
The first approach is classic OOP style. Creation of an object is separated from adding an object into some collection. This way code consumer can substitute an object of a concrete class (e.g. Car) with an object of any derived class (e.g. TrailerCar).
// var model = CarsModel.Create (company, "Tiana");
var model = TrailerCarsModel.Create (
company, "Tiana", SimpleTrailer.Create(company));
company.AddModel (model);
Try adopting this business logic change in the 2nd / 3rd approach.
I've got acceptable answer here: https://groups.yahoo.com/neo/groups/domaindrivendesign/conversations/messages/23187
Basically, it's a combination of method 2 and 3 - put AddModel method into the CarsCompany and make it call protected internal constructor of the CarsModel with name parameter which is validated inside the CarsModel's constructor.