Simon
Simon

Reputation: 181

Where should I check for uniqueness in a ddd architecture

In my domain model I have a customer aggregate root. My business rule is -> I can not add a new customer with the same firstname, lastname and email address. Where is the best place for this kind of validation check?

First from my point of view its completely wrong to place this kind of check inside of my customer aggregate. Second it also feels unnatural to add this validation inside of my CustomerRepository as I want to treat them just as simple in memory collections with mainly the same logic for all my aggregates. Third i am also not going to add this check inside of my CreateCustomer-Command because then this important check is outside of my domain model.

So the last option I see is to create a CustomerService class and put this kind of validation here.

Do you have any other recommendation? I already read many of other posts but they don't really give a clear answer... Thanks!!

Upvotes: 0

Views: 502

Answers (1)

VoiceOfUnreason
VoiceOfUnreason

Reputation: 57277

The general term for the problem you are describing is set validation.

If it is acceptable to the business that the invariant be violated for short periods of time, then you establish a process that monitors all of your customer aggregates looking for conflicts, and notifying some remediation process if one is discovered. You can reduce (but not eliminate) the risk of collisions by incorporating a check for prior entries into your business logic; there's still the possibility that the constraint will be violated in a data race.

If it is not acceptable to do that (perhaps the legal or financial implications are too severe) then things get harder.

One answer that will sometimes work is to take the values that must be unique, and use those to generate a unique identifier for the aggregate. Unfortunately, first name, last name, and email address are not stable enough to be good candidates for that approach (what happens if your customer changes their email address? or their legal name?)

That leaves having a lock on the entire set of customers when you make a modification to one of them. That might be as simple as forcing any process that is going to modify a customer to acquire a shared lock, or by putting all of the customers into a single aggregate, or programming the constraint into your storage (think constraints in an RDBMS).

Upvotes: 1

Related Questions