IValidatableObject vs Single Responsibility

11

Mi piace il punto di estensibilità di MVC, che consente ai modelli di visualizzazione di implementare IValidatableObject e di aggiungere la convalida personalizzata.

Cerco di mantenere i miei controllori snelli, visto che questo codice è l'unica logica di convalida:

if (!ModelState.IsValid)
    return View(loginViewModel);

Ad esempio, un modello di vista di accesso implementa IValidatableObject, ottiene l'oggetto ILoginValidator tramite l'iniezione del costruttore:

public interface ILoginValidator
{
    bool UserExists(string email);
    bool IsLoginValid(string userName, string password);
}

Sembra che Ninject, iniettando istanze nei modelli di vista non sia davvero una pratica comune, potrebbe anche essere un anti-pattern?

È un buon approccio? C'è uno migliore?

    
posta Boris Yankov 15.06.2012 - 14:13
fonte

3 risposte

6

Personalmente, per me il tuo design sembra pulito.

IValidatableObject significa che il modello di visualizzazione fornirà alcune convalide che non possono essere fornite da semplici attributi - iniettando il vero validatore che chiamerà servizi / database / qualsiasi cosa mantenga pulito il tuo progetto e ti garantisca non violare il principio di responsabilità unica - Visualizza i modelli sono responsabili, in sostanza, per il trasferimento di dati e la convalida dei dati che vengono trasferiti (sia tramite attributi o IValidatableObject o entrambi).

    
risposta data 15.06.2012 - 15:47
fonte
3

Avere un oggetto dedicato per la convalida garantisce che si rispetti effettivamente SRP - che era già il caso in ogni caso dal momento che è una tipica responsabilità di un modello di vista per convalidare i suoi dati.

Per quanto riguarda l'iniezione di istanze in modelli di vista, non riesco a vedere nulla di sbagliato in questo. Non c'è praticamente alcun limite a ciò che può essere iniettato in cosa.

    
risposta data 15.06.2012 - 16:09
fonte
2

Invece di iniettare ILoginValidator nel tuo costruttore VM, puoi usare ValidationContext (che è l'argomento di IValidatableObject.Validate ()) per ottenere il tuo Validator.

public IEnumerable<ValidationResult> Validate(ValidationContext vc)
{

var loginValidator = (ILoginValidator)vc.GetService(typeof(ILoginValidator));
return loginValidator.Validate();

}
    
risposta data 26.10.2012 - 19:01
fonte