1

I am modelling UserAggregate using DDD concepts. I know that two separate users should be independent, but when creating a new user, I need to validate, that there is no other user with the same username. How do I approach such a situation?

One potential solution to this is for UserAggregate to depend on IUserRepository and that way to check that the username is unique. This is clearly not ideal. Another solution would be to create UsersAggregate that contains all of the users in my system, but that is obviously absurd. Therefore I am stuck with option number 1, but still wondering what is the DDD-esque solution to this problem.

2

I am modelling UserAggregate using DDD concepts. I know that two separate users should be independent, but when creating a new user, I need to validate, that there is no other user with the same username. How do I approach such a situation?

The search term for this sort of problem is set validation.

Some common answers

1) You investigate, and discover that the "rule" really isn't all that important to the business, and so you make a best effort at avoiding collisions, and have incident / exception reports that detect possible conflicts for human resolution. "If that name wasn't in use a second ago, good enough -- we'll deal with the data races by hand."

2) You punt, and put the burden of maintaining the business rule on the storage appliance. Which is to say, you store all of the users in a relational database, and enforce the uniqueness constraint there. This doesn't fit all storage options -- NoSQL storage will likely have a problem here.

3) You update your model, so that the set that needs to be valid is an aggregate unto itself. For a case like this one, the "set" would probably be something like a map of user names onto user identifiers.

4) You update your process, so that all requests for a given user name are routed to the same user aggregate - analogous to using the user name as the user identifier.

5) You recognize that user management is not a concern unique to your business, and you find an off the shelf solution, and adapt your processes to it. If users aren't your core business, this is often the right way to go.

4

I'm assuming UserAggregate is supposed to model a User? In which case user creation should arguably not be in it. Whoever actually "creates" users could check whether the username is unique, and yes, it should have any and all dependencies it needs to do that.

If UserAggregate is not a User than it's probably a technical class in which case the design is already a bit off.

Two followup thoughts:

  1. Pick class names that are meaningful. Meaningful means a business person (familiar with the subject matter) would understand what it is. UserAggregate is technical hence not a good name.

  2. Most databases (relational or otherwise) would catch a non-unique key, don't be afraid to delegate if you can.

2

In a case like this you can consider that this validation rule doesn't fit in your domain logic. In that case, this validation logic should occur in your application service layer, when validating the input command :

  • a CreateUser command is received with the username as payload
  • the command handler in your application service checks that the username is unique by using your UserRepository
  • the command is accepted or rejected depending on this rule

If you do think that this validation process belongs to your domain logic, you can use a DomainService instead of the Application service to handle this logic. The steps are the same but the verification is handled by some kind of UserValidationService Domain Service (name it better than me, with some language that reflects your ubiquitous language in that case).

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.