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
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)