Closed ferrius closed 5 years ago
Hi @ferrius
In SignUp we handle this by UserFactory
doing this:
class UserFactory
{
public function register(UuidInterface $uuid, Credentials $credentials): User
{
if ($this->userCollection->existsEmail($credentials->email)) {
throw new EmailAlreadyExistException('Email already registered.');
}
return User::create($uuid, $credentials);
}
The specification pattern can help also with this removing some code and being more DRY. Good catch 👍
Hi, I think a domain service (interface + implementation) should be better for this type of 'domain rule', not all domain rules must be aggregates invariant. Check uniqueness requirement inside aggregate is not a good idea in this case. Maybe this article can clarify a little bit the difference. Email uniqueness as an aggregate invariant
Thank you for the article. But see the next article of this author and especially discussion in the comments.
I think the point here is that it's needed in more than one place so the UserFactory is taking this responsibility and as soon as this is needed in other places, it gets invalidated. It can also be validated in the application layer (command handler) but I prefer be as close as possible to the domain layer
Feedback appreciated here #99 ;)
First of all, thank you for a great example!
We have an aggregate domain rule "user must have an unique email", but we have just one assertion in factory. This is not a defensive way. In DDD domain object is permanently valid and can be used in stand alone manner. You can use specification pattern for validating aggregate rules.
The same in User::create