Я действительно изо всех сил пытаюсь создать основанные на интерфейсе / соглашениях правила для FluentValidator.Он имеет следующий класс
abstract class AbstractValidator<T>
{
IRuleBuilderInitial<T, TProperty> RuleFor<TProperty>(Expression<Func<T, TProperty>> expression)
...
}
public interface IWithPropertyA
{
string PropertyA{get;set;}
}
public interface IWithPropertyB
{
string PropertyB{get;set;}
}
public class Handler1Data: IWithPropertyA
{
public string PropertyA {get;set;}
}
public class Handler2Data: IWithPropertyA, IWithPropertyB
{
public string PropertyA {get;set;}
public string PropertyB {get;set;}
}
public class Handler1 : AbstractValidator<Handler1Data> {}
public class Handler2 : AbstractValidator<Handler2Data> {}
Я пытаюсь создать метод расширения, который в основном проверяет, реализует ли универсальный аргумент конкретный интерфейс, а затем добавляет к нему правило:
public static void ValidateAll<T>(this AbstractValidator<T> validator)
{
(validator as AbstractValidator<IWithPropertyA>)?.RuleFor(x => x.PropertyA).NotEmpty().WithMessage("PropertyA Missing");
(validator as AbstractValidator<IWithPropertyB>)?.RuleFor(x => x.PropertyB).NotEmpty().WithMessage("PropertyB Missing");
}
Проблема здесьОчевидно, что AbstractValidator не является ковариантным, поэтому валидатор не может быть преобразован ни в AbstractValidator<PropertyA>
, ни в AbstractValidator<PropertyB>
.Я попытался создать свой собственный базовый валидатор, как показано ниже, а затем создать метод расширения на основе этого, но я не могу.
public interface IMyValidator<in T>
{
void AddMyRule<TProperty>(Expression<Func<T, TProperty>> expression) //it doesn't work because Expression<Func<T,Property> cannont be covariant
}
public abstract class MyBaseValidator<T>: AbstractValidator<T> ,IMyValidator<T>
{
void AddMyRule<TProperty>(Expression<Func<T, TProperty>> expression)
}
Метод будет вызываться в каждом обработчике следующим образом:
public class Handler1 : AbstractValidator<Handler1Data> {
this.ValidateAll();
}