DDD: It's correct to use Domain Events to guarantee invariants consistency? Do I have alternatives?

283 Views Asked by At

In my domain model I have the project entity (which is also aggregate root) which has products entity as child. One of the invariants of my domain model is that I can't have two products with the same code children of the same project (but is ok if the project is different).

My products are composed by parts which also has a similar rule (every part must have unique code within the same product) so parts are child of products because I need to ensure that rule. Children of product are also the activities that I need to do to create it because I'm describing a production tracking system.

Now, activities can have subactivities which can be assigned to factory area and so on.

Substantially what I have is that all entities starts from project just because I need to ensure one invariant(=business rule) but is not the best solution because every time I need to retrieve an entity I need to fill all the project (which can have 2000+ products).

What can I do to split that preserving my invariant but also freeing me to load a specific activity (or product) without retrieving all products of my project every time I need a child entity?

Should I need to split the Entities in several AggregateRoots, maintaining in the project a list of ProjectProductValueObject(string code) and use Domain Events in Aggregate's constructor to fire something like ProductCreatedEvent which try to create and add a new ProjectProductValueObject in my project using the AddProduct(ProjectProductValueObject product) method which contain my business rule and throws an exception if that's not satisfied? Is that ok and compliant to DDD principles?

Do I have other alternatives?

1

There are 1 best solutions below

0
On

I have the feeling that you're overcomplicating the model. From your description I've understood that:

  1. Projects are root entities that can contain a list of
  2. AssignedProduct, that is another root entity that contains a binding between the project (its id, see as a value object) and the product (I see it also as a value object)
  3. So on with object and assigned object

In this way you've several Products that could be assigned to several Projects, but only the ones stored in AssignedProduct are valid. To avoid multiple assignments is just a matter of checking if the same couple of objects are already bound together.

If this doesn't match your model, ignore it.