IValidatableObject vs Single Responsibility


12

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

Cerco di mantenere i miei controller snelli, avendo questo codice come unica logica di validazione:

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 in realtà una pratica comune, potrebbe anche essere un anti-pattern?

è un buon approccio? Ce n'è uno migliore?


Se si desidera la convalida in un oggetto separato, provare FluentValidation. Vedi fluentvalidation.codeplex.com/wikipage?title=mvc .
rmac,

+1 Ottima idea di iniettare una classe Validator separata, che risolve il mio problema in cui devo accedere alle informazioni del database per la convalida!
magnattico,

Risposte:


7

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 validatore reale che chiamerà servizi / database / qualunque cosa mantenga pulito il tuo progetto e assicuri di non violare il principio di responsabilità singola - Visualizza i modelli sono responsabile, essenzialmente, del trasferimento dei dati e della convalida dei dati trasferiti (sia tramite attributi o IValidatableObject o entrambi).


4

Avere un oggetto dedicato per la validazione garantisce che tu rispetti davvero SRP, il che era già il caso, dato che è una responsabilità tipica di un modello di visualizzazione convalidare i suoi dati.

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


3

Invece di iniettare ILoginValidator nel costruttore della macchina virtuale, puoi usare ValidationContext (che è l'arg su IValidatableObject.Validate ()) per ottenere il tuo validatore.

public IEnumerable<ValidationResult> Validate(ValidationContext vc)
{

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

}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.