FluentValidation: How to inject all registered validators?

Viewed 811

I'm using FluentValidation.AspNetCore library (Version="10.3.3") for a .Net Core project.

To register validators i use this: services.AddValidatorsFromAssemblyContaining<TestValidator>();

For example i have class called Test and i can inject validator for this class like this:

    public class Service : IService
    {
        private readonly IValidator<Test> _testValidator;

        public Service(IValidator<Test> testValidator)
        {
            _testValidator = testValidator;
        }
   }

But i dont know how to inject all registered validators into my Service constructor as IEnumerable instance. So what is the correct way to do it?

1 Answers

FluentValidation's AddValidatorsFromAssemblyContaining registers all validators implementing IValidator<T> from assembly as generic interface and self so you can resolve them only by concrete type or constructed generic (i.e. IValidator<Test>) i.e. it is not possible to resolve all of them as a single collection.

If you really want you can try leveraging that IValidator<T> inherits IValidator and use next little bit hacky solution:

services.AddValidatorsFromAssemblyContaining(typeof(Val1));

// Only after all validators registrations
var serviceDescriptors = services
    .Where(descriptor => typeof(IValidator) != descriptor.ServiceType
           && typeof(IValidator).IsAssignableFrom(descriptor.ServiceType)
           && descriptor.ServiceType.IsInterface)
    .ToList();

foreach (var descriptor in serviceDescriptors)
{
    services.Add(new ServiceDescriptor(
        typeof(IValidator),
        p => p.GetRequiredService(descriptor.ServiceType),
        descriptor.Lifetime));
}

After that you will be able to resolve IEnumerable<IValidator>. Though not sure that this will be much help for you.

Related