Tengo una jerarquía de clases de datos.
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 }¿Cuál sería la forma adecuada de validar Derived1 y Derived2 utilizando el marco FluentValidation sin duplicar las reglas para los campos de la clase Base?
public class Derived2Validator : AbstractValidator<Derived2> { public Derived2Validator() { Include(new BaseValidator()); Include(new Derived1Validator()); RuleFor(d => d.Derived1Name).NotNull(); } } Derived2Validator no necesita heredar BaseValidator o Derived1Validator .
Utilice el método de Include para incluir las reglas de otros validadores.
Un enfoque a tomar sería el siguiente:
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(); } } Entonces, primero crea su validador base, lo hace aceptar un argumento de tipo genérico y especifica que el tipo genérico debe ser de tipo base . Configure sus reglas generales para su clase base y siga adelante.
Para cualquier validador que valide a los niños de su clase base, tiene esos validadores heredados del baseValidator, donde T será su tipo de clase derivada.
Probé el método include(), pero eso no me dio los resultados deseados ya que los modelos generados por swagger en .net core no mostraron ningún cambio. lo que funcionó fue crear una nueva clase para heredar para los validadores que tienen una clase base
/// <summary> /// Base Class for entity validator classes that specifies a base validator class /// </summary> /// <typeparam name="T">The Type being validated</typeparam> /// <typeparam name="TBaseClass">The validater assigned to the base type of the type being validated</typeparam> public abstract class BaseAbstractValidator<T, TBaseClass> : AbstractValidator<T> where TBaseClass : IEnumerable<IValidationRule> { protected BaseAbstractValidator() => AppendRules<TBaseClass>(); /// <summary> /// Add the set of validation rules /// </summary> /// <typeparam name="TValidationRule"></typeparam> private void AppendRules<TValidationRule>() where TValidationRule : IEnumerable<IValidationRule> { var rules = (IEnumerable<IValidationRule>)Activator.CreateInstance<TValidationRule>(); foreach (var rule in rules) { AddRule(rule); } } }