Search code examples
c#.net-coredependency-injectionstartupfluentvalidation

FluentValidation: How to inject all registered validators?


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?


Solution

  • 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 the following (a 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.