2015-06-09 13 views
18

ho una gerarchia di classi di datiC# FluentValidation per una gerarchia di classi

public class Base 
{ 
    // Fields to be validated 
} 

public class Derived1 : Base 
{ 
    // More fields to be validated 
} 

public class Derived2 : Base 
{ 
    // More fields to be validated 
} 

Quale sarebbe il modo appropriato per convalidato Derived1 e Derived2 utilizzando il framework FluentValidation senza duplicare le regole per i campi della classe di base?

risposta

24

Un approccio per prendere sarebbe la seguente:

public class Base 
{ 
    public string BaseName { get; set; } 
} 

public class Derived1 : Base 
{ 
    public string Derived1Name { get; set; } 
} 

public class BaseValidator<T> : AbstractValidator<T> where T : Base 
{ 
    public BaseValidator() 
    { 
     RuleFor(b => b.BaseName).NotNull(); 
    } 
} 

public class Derived1Validator : BaseValidator<Derived1> 
{ 
    public Derived1Validator() 
    { 
     RuleFor(d => d.Derived1Name).NotNull(); 
    } 
} 

Quindi prima creare il validatore di base, ne fanno accettare un argomento di tipo generico e specificare che il tipo generico deve essere di tipo base. Imposta le tue regole generali per la tua classe base e vai avanti.

Per tutti i validatori che convalidano i figli della classe base, questi convalidatori ereditano da baseValidator, dove T sarà il tipo di classe derivata.

+1

Grazie per la risposta! –

+0

Perfetto! Funziona come un fascino! Notato che non è necessario aggiungere: base() dopo il costruttore derivato. Inizialmente, avevo pensato che non avrebbe raccolto i test di base senza chiamare esplicitamente il costruttore di base. Ma lo fa! –

+0

Non hai bisogno di aggiungere base() se non hai costruttori, perché è lì automaticamente. Se avessi altri costruttori, a parte il default vuoto, devi usare base() usando la firma che ti serve. Nelle classi di validazione ... probabilmente non avrai mai bisogno di aggiungere altri costruttori diversi. – ppumkin

22
public class Derived2Validator : AbstractValidator<Derived2> 
{ 
    public Derived2Validator() 
    { 
     Include(new BaseValidator()); 
     Include(new Derived2Validator()); 
     RuleFor(d => d.Derived1Name).NotNull(); 
    } 
} 

Derived2Validator non ha bisogno di ereditare BaseValidator o Derived1Validator. Il metodo Include includerà le regole dai validatori di base.

+10

Mi piacerebbe seguire questo approccio in quanto favorisce la composizione sull'ereditarietà, che è una regola d'oro per i buoni sviluppatori –

Problemi correlati