Sto provando a modellare la sicurezza del mio progetto usando DDD ma sono finito in un vicolo cieco.
Ho le classi User
, UserA
e UserB
che sono state modellate come segue. Ciò che cambia in pratica è che gli oggetti UserA
hanno una politica di accesso diversa da UserB
e per questo ho pensato di utilizzare il pattern STRATEGY come una buona opzione.
public abstract class User
{
public int UserId { get; set; }
public string Login { get; set; }
public string PasswordHash { get; set; }
}
public class UserA : User
{
// custom UserA properties and methods
}
public class UserB : User
{
// custom UserB properties and methods
}
public interface IAccessPolice {}
public class EvenAccessPolice : IAccessPolice
{
// string just for simplify but it is a Service
private readonly string _someDependencyInjected;
public EvenAccessPolice(string someDependencyInjected)
{
_someDependencyInjected = someDependencyInjected;
}
public bool CanAccess(UserA user)
{
// authentication logic for UserA
return user.UserId % 2 == 0;
}
}
public class OddAccessPolice : IAccessPolice
{
public bool CanAccess(UserB user)
{
// authentication logic for UserB
return user.UserId % 2 != 0;
}
}
public class AuthenticationService
{
public IList<User> _userRepository = new List<User>();
public bool CheckIfUserCanLogin(int userId)
{
var user = _userRepository.Where(u => u.UserId == userId).FirstOrDefault();
// this if is annoing me
if (user is UserA)
{
var authPolice = new EvenAccessPolice("Inject this value...");
return authPolice.CanAccess(user as UserA);
}
else
{
var authPolice = new OddAccessPolice();
return authPolice.CanAccess(user as UserB);
}
}
}
AuthenticationService
ottiene l'istanza utente ( UserA
o UserB
) e controlla se l'utente può o meno accedere al sistema. L'istruzione if
utilizzata per decidere quale delle politiche deve essere eseguita è un codice che mi sembra strano dal momento che il mio servizio non verrà chiuso quando dovrò aggiungere / modificare le politiche.
Poiché la politica è legata al sottotipo user
, ho pensato di inserire una proprietà in UserA
e UserB
che restituirebbe l'istanza corretta di IAccessPolice
, ma che mi obbligherebbe a caricare EvenAccessPolice
di dipendenze nella mia entità di dominio, e penso che non sia un'opzione (odore di codice).
C'è un modo per acquisire IAccessPolice
da user
senza utilizzare un'istruzione if
?