1

I have a single class

public class Foo
{
    public string Name { get; set;}
    public string Email { get; set;}
    public int Id { get; set;}
}

And my objective is to have 2 differents rules in a FluentValidators for this class. Because i want to be able to check them in different context (ex: i dont need to use the Email Validator when a bool _canSendEmail is false)

So I started by creating 2 FluentValidators like this

public class MailValidator<T> : AbstractValidator<T>
    where T : Foo
{
    public MailValidator()
    {
        RuleFor(f => f.Email).NotNull();
    }
}

public class NameValidator<T> : AbstractValidator<T>
    where T : Foo
{
    public NameValidator()
    {
        RuleFor(f => f.Name).NotNull();
    }
}

And I inject them in Programm.cs

   builder.Services.AddScoped<IValidator<Foo>, NameValidator>();
   builder.Services.AddScoped<IValidator<Foo>, EmailValidator>();

This Solution worked when i want to access to the Validator like this

   private readonly EmailValidator _eamilValidator;

But caused some Dependencies injection error on another project that i couldn't fix because it's accessing to it using this: private readonly IValidator<Foo> _validator;

So my question is: Is there a way to declare a Validator with multiple configuration or function?

In my idea something like this:

public class FooValidator<T> : AbstractValidator<T>
    where T : Foo
{
    public FooValidator()
    {
        ValidateName() // Default call so the other project can acces the validator he needs
    }

    public ValidateMail()
    {
        RuleFor(f => f.Email).NotNull();
    }

    public ValidateName()
    {
        RuleFor(f => f.Name).NotNull();
    }
}
5
  • This might help you: stackoverflow.com/questions/13198471/… Is it considered a duplicate? Commented Sep 9, 2024 at 16:05
  • I saw this one and i dont have the same need because its not for many class its for an unique one so for me its not duplicate @PabloCampana Commented Sep 9, 2024 at 21:49
  • 1
    Sorry, I don't think this can help you but to me, this seems over-complicated. If you validate the same class/interface, you should put them into a single validator instead of multiple. Unless you have interface like IHasName (with Name property) or IHasEmail (with Email property), then I can see the purpose of declaring multiple validator classes. Commented Sep 10, 2024 at 0:30
  • @YongShun this is a simplified example, my need is too be able to validate some sort of a blazor forms where all the value are stored. But i need a temporal save that need to check only few things and also a submit validator that check everything is needed for me Commented Sep 10, 2024 at 5:34
  • As suggested in answer as well as in linked post, you can inject collection of validators and use them Commented Sep 10, 2024 at 9:16

1 Answer 1

2

A solution that i found is to declare both of the validator like before and to add them like this

builder.Services.AddScoped<IValidator<Foo>, NameValidator>();
builder.Services.AddScoped<IValidator<Foo>, EmailValidator>();

Then, whenever I want to Use à single validator I can do this:

[Inject] public IEnumerable<IValidator<Foo>> Validators { get; set; }

And Select the good one by doing a simple Validators.First(val => val is EmailValidator)

It's the only way that i found and it made me change a lot of things so any suggestion are welcome

Sign up to request clarification or add additional context in comments.

1 Comment

Cool answer, didn't know about ability of multiple validators being registered and resolved. Rulesets preferable for case of question, but this ability is more "low-level" and must have attention of FluentValidation community. Big +1!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.