dataannotations - C#FluentValidation para una jerarquía de clases
fluent validation mvc (3)
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 de FluentValidation sin duplicar las reglas para los campos de la clase Base?
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 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);
}
}
}
Un enfoque a seguir 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();
}
}
Así que primero crea su validador de base, haga que acepte un argumento de tipo genérico y especifique que el tipo genérico debe ser de tipo base
. Configura tus reglas generales para tu clase base y sigue adelante.
Para cualquier validador que valide elementos secundarios de su clase base, tiene esos validadores heredados del baseValidator, donde T será su tipo de clase derivado.
public class Derived2Validator : AbstractValidator<Derived2>
{
public Derived2Validator()
{
Include(new BaseValidator());
Include(new Derived2Validator());
RuleFor(d => d.Derived1Name).NotNull();
}
}
Derived2Validator
no necesita heredar BaseValidator
o Derived1Validator
. El método Include
incluirá las reglas de los validadores de base.