Okay, so, I'm working on an AuthService for my microservices system.
I'm putting plenty of logic around single instance of User inside of it itself, just so I can avoid repeating code, breaking SRP or anemic domain models.
.. but now I've stumbled upon a certain problem, to be precise:
I have this method inside User
entity:
public Token SignIn(string username, string password)
{
if (string.IsNullOrEmpty(username))
throw new ArgumentNullException("Username cannot be null or empty");
if (string.IsNullOrEmpty(password))
throw new ArgumentNullException("Password cannot be null or empty");
if (Password != password)
throw new Exception("Password mismatch");
return Token.Create(this, TokenType.Session, "???");
}
The problem with this is, token value is supposed to be generated via ITokenValueProvider.
I only see 4 solutions to this problem - all but one of them would break SRP, create a leaky abstraction or break DDD.
a) Add string tokenValue
to SignIn
and then generate value on the service and push it deeper.
e.g.: public Token SignIn(string username, string password, string tokenValue)
b) Add ITokenValueProvider tokenizer
to SignIn
and then generate it inside User.SignIn
c) Add ITokenValueProvider tokenizer
to public static Token.Create()
and then generate it there.
d) Replace SignIn with CanSignIn
and then generate token on the service - this solution is the one that would cause no antipatterns, other than being generally ugly and disallows me to store logic around signing-in inside the entity.
Any ideas :) ?
Token
is part of your domain, rather, an implementation detail within your application/infrastructure layer. Keep it there. We could imagine all sorts of different ways of managing auth from an application-level PoV right? d is the best solution listed above, but keep the nameSignIn
and don't return abool
(just throw). To be completely honest though, I don't think any of the above should be in your domain.User
doesn't sound like a DDD entity to me. What doUsers
do?