'FluentValidation multiple validators

Can I add more than one validator to an object? For example:

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 FooBarValidator : AbstractValidator<FooBar>
{
    public FooBarValidator()
    {
        RuleFor(x => x)
            .SetValidator(new FooValidator())
            .SetValidator(new BarValidator());
    }
}

Running the test.

FooBarValidator validator = new FooBarValidator();
validator.ShouldHaveValidationErrorFor(x => x.Id, 0);

I get an InvalidOperationException:

Property name could not be automatically determined for expression x => x. Please specify either a custom property name by calling 'WithName'.

Is there any way to implement this or am I trying to use FluentValidation in a way that it's not meant to be used?



Solution 1:[1]

Another possibility would be to override Validate:

public override ValidationResult Validate(ValidationContext<FooBar> context)
{
    var fooResult = new FooValidator().Validate(context.InstanceToValidate);
    var barResult = new BarValidator().Validate(context.InstanceToValidate);

    var errors = new List<ValidationFailure>();
    errors.AddRange(fooResult.Errors);
    errors.AddRange(barResult.Errors);

    return new ValidationResult(errors);
}

Solution 2:[2]

"Including Rules. You can include rules from other validators provided they validate the same type."

public class PersonValidator : AbstractValidator<Person> {
    public PersonValidator() {
        Include(new PersonAgeValidator());
        Include(new PersonNameValidator());
    }
}

https://docs.fluentvalidation.net/en/latest/including-rules.html

Solution 3:[3]

You could use RuleSets to apply different types of validation if that helps with what you are trying to do:

FluentValidation RuleSets

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Jeff Smith
Solution 2 Ignas
Solution 3 Patrick