Unique verification in DDD

I have a question regarding uniqueness checking in DDD. I already have some questions about this in stackoverflow, but they really don't answer my doubts.

Is it possible for the aggregated root to maintain a link to the repository to verify uniqueness when updating / inserting into the database? Or is it a task performed by an application service instead of a domain model?

Let's say I want to check if the username of the user model is unique when the user logs in. There are several approaches that I can think of:

  • Link to UserRepository user model, perform uniqueness check in Validate ()
  • Create a domain service to perform uniqueness checking using UserRepository (this seems a little strange for me because I think that usually a domain service is used only if the logical range exceeds several domain models).
  • Create a specification object in the domain layer with a link to UserRepository to encapsulate a unique validation rule, and the application service level uses this to verify before updating / inserting

And if I use dependency injection, I still wonder how to enter a UserRepository in User in approach 1 or a domain service in approach 2 or an application service in approach 3, because in any case for the User / domain / service specification of the object, I need to create an instance of the object manually, so the only option with which I seem to use the service locator in IoC to get the instance. But the service locator is an anti-pattern, so I want to avoid it.

Any code sample would be much appreciated.

+6
source share
1 answer

I think that checking for uniqueness is the responsibility of the repository. The repository knows about all aggregates, because it intends to simulate a collection of domains, so it is natural to set a repository of uniqueness (for example, what you expect from HashMap, for example).

// repository interface Users { // implementation executes SQL COUNT in case of relation DB bool IsNameUnique(String name); // implementation will call IsNameUnique and throw if it fails void Add(User user); } 

This is an opaque abstraction in a sense, because in a multi-user environment, it must be applied on the side of the data warehouse (for example, a UNIQUE SQL constraint or a lock).

IsNameUnique should probably not be called from a user aggregate; I would move this call to the application or domain service, depending on how the rest of your application is structured.

See Uniqueness Verification in the CQRS architecture for an alternative approach.

+4
source

Source: https://habr.com/ru/post/946142/


All Articles