Ответ 1
RuleFor пытается создать правило уровня собственности. Вы можете дополнительно использовать функцию AddRule для добавления правила общего назначения.
Используя это, я создал составное правило, подтверждающее концепцию. Он принимает множество других валидаторов и запускает их. Код yield break
поступал прямо из FluentValidator
DelegateValidator
. Я не был уверен, что с этим делать, поэтому я схватил это из источника. Я не проследил его цели, но все работает так:)
Код
public interface IFoo
{
int Id { get; set; }
string Name { get; set; }
}
public interface IBar
{
string Stuff { get; set; }
}
public class FooValidator : AbstractValidator<IFoo>
{
public FooValidator()
{
RuleFor(x => x.Id).NotEmpty().GreaterThan(0);
}
}
public class BarValidator : AbstractValidator<IBar>
{
public BarValidator()
{
RuleFor(x => x.Stuff).Length(5, 30);
}
}
public class FooBar : IFoo, IBar
{
public int Id { get; set; }
public string Name { get; set; }
public string Stuff { get; set; }
}
public class CompositeValidatorRule : IValidationRule
{
private IValidator[] _validators;
public CompositeValidatorRule(params IValidator[] validators)
{
_validators = validators;
}
#region IValidationRule Members
public string RuleSet
{
get; set;
}
public IEnumerable<ServiceStack.FluentValidation.Results.ValidationFailure> Validate(ValidationContext context)
{
var ret = new List<ServiceStack.FluentValidation.Results.ValidationFailure>();
foreach(var v in _validators)
{
ret.AddRange(v.Validate(context).Errors);
}
return ret;
}
public IEnumerable<ServiceStack.FluentValidation.Validators.IPropertyValidator> Validators
{
get { yield break; }
}
#endregion
}
public class FooBarValidator : AbstractValidator<FooBar>
{
public FooBarValidator()
{
AddRule(new CompositeValidatorRule(new FooValidator(), new BarValidator()));
}
}
Базовый тестовый пример:
[TestMethod]
public void TestValidator()
{
FooBarValidator validator = new FooBarValidator();
var result = validator.Validate(new FooBar());
}
Надеюсь, это поможет.