Dan*_*618 4 c# fluentvalidation simple-injector
我正在尝试自动验证我的视图模型,我知道我可以添加一个属性来指定我的验证,但是有一个选项可以设置工厂来自动化所有这些,我看着:这个答案并提出来了这使用简单的注射器3.1:
public class CustomValidatorFactory:ValidatorFactoryBase
{
private readonly Container siContainer;
public CustomValidatorFactory(Container siContainer)
{
var assemblies = AppDomain.CurrentDomain.GetAssemblies().ToList();
this.siContainer = siContainer;
this.siContainer.Register(typeof(IValidator<>), assemblies);
}
public override IValidator CreateInstance(Type validatorType)
{
//var instances = siContainer.GetAllInstances(validatorType);
var implementation = ((IServiceProvider)siContainer).GetService(validatorType);
var validatorInstance = implementation != null ? (implementation as IValidator) : null;
return validatorInstance;
}
}
Run Code Online (Sandbox Code Playgroud)
然后视图模型可以是类似的
public class Person {
public int Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public int Age { get; set; }
}
public class PersonValidator : AbstractValidator<Person> {
public PersonValidator() {
RuleFor(x => x.Id).NotNull();
RuleFor(x => x.Name).Length(0, 10);
RuleFor(x => x.Email).EmailAddress();
RuleFor(x => x.Age).InclusiveBetween(18, 60);
}
}
Run Code Online (Sandbox Code Playgroud)
但是实现变量总是为null,我也尝试过RegisterCollection但仍然有相同的问题,看起来简单的注入器不知道如何在验证器继承自AbstractValidator时解析IValidator(这是实现IValidator的类)
在Simple Injector中注册Fluent验证工厂,如下所示:
public class ApplicationValidatorFactory : IValidatorFactory
{
private readonly Container _container;
/// <summary>The constructor of the factory.</summary>
/// <param name="container">The Simple Injector Container</param>
public ApplicationValidatorFactory(Container container)
{
_container = container;
}
/// <summary>Gets the validator for the specified type.</summary>
public IValidator<T> GetValidator<T>()
{
return _container.GetInstance<IValidator<T>>();
}
/// <summary>Gets the validator for the specified type.</summary>
public IValidator GetValidator(Type type)
{
var validator = typeof(IValidator<>).MakeGenericType(type);
return (IValidator)_container.GetInstance(validator);
}
}
Run Code Online (Sandbox Code Playgroud)
然后在您的Composition Root中为ASP.NET MVC注册它:
// Register the validators and factory
var assemblies = AppDomain.CurrentDomain.GetAssemblies().ToList();
container.Register<IValidatorFactory, ApplicationValidatorFactory>(Lifestyle.Singleton);
container.Register(typeof(IValidator<>), assemblies);
// Register Simple Injector validation factory in FV
FluentValidationModelValidatorProvider.Configure(provider => {
provider.ValidatorFactory = new ApplicationValidatorFactory(container);
provider.AddImplicitRequiredValidator = false;
}
);
Run Code Online (Sandbox Code Playgroud)
在FluentValidationModelValidatorProvider被发现的FluentValidation.MVC集成软件包.记得为你正在运行的MVC版本获取一个.
UPDATE
您可以为没有验证器的对象注册一个空的验证器,如:
/// <summary>
/// Adds an unregistered type resolution for objects missing an IValidator.
/// </summary>
/// <typeparam name="T">The type.</typeparam>
internal sealed class ValidateNothingDecorator<T> : AbstractValidator<T>
{
// I do nothing :-)
}
// Add unregistered type resolution for objects missing an IValidator<T>
// This should be placed after the registration of IValidator<>
container.RegisterConditional(typeof(IValidator<>), typeof(ValidateNothingDecorator<>), Lifestyle.Singleton, context => !context.Handled);
Run Code Online (Sandbox Code Playgroud)