Search code examples
c#fluentvalidation

FluentValidation: AddValidatorsFromAssemblyContaining<T> results in IValidator<T> not registered


I'm trying to use FluentValidation to validate based on object.GetType() rather than knowing the type at compile time by injecting IValidator<T>, but I am getting null values instead of a valid validator.

Organisation + Validator

namespace ConsoleApp44
{
    internal class Organisation
    {
        public string? Name { get; set; }
    }

    internal class OrganisationValidator: AbstractValidator<Organisation>
    {
        public OrganisationValidator()
        {
            RuleFor(x => x.Name).NotEmpty();
        }
    }
}

Console app that consumes it

var services = new ServiceCollection();
services.AddValidatorsFromAssemblyContaining<OrganisationValidator>();
services.Add(ServiceDescriptor.Scoped(typeof(IValidatorFactory), typeof(ServiceProviderValidatorFactory)));

var sp = services.BuildServiceProvider();
var org = new Organisation();
var validationFactory = sp.GetRequiredService<IValidatorFactory>(); // Not null
var validator = validationFactory.GetValidator(org.GetType()); // Null
validator = validationFactory.GetValidator<Organisation>(); // Null
validator = sp.GetRequiredService<IValidator<Organisation>>(); // Exception, IValidator<Organisation> not registered

Solution

  • As far as I know services.AddValidatorsFromAssemblyContaining<OrganisationValidator>(); doesn't see internal classes by default. https://docs.fluentvalidation.net/en/latest/di.html

    You can just make OrganisationValidator public

    Or, if version of your FluentValidation package is high enough (I think >=11.0) you can set parameter includeInternalTypes of AddValidatorsFromAssemblyContaining to true like so: services.AddValidatorsFromAssemblyContaining<OrganisationValidator>(includeInternalTypes: true)