impleInjector和FluentValidationFa

impleInjector和FluentValidationFa

本文介绍了SimpleInjector和FluentValidationFactory的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试自动执行视图模型的验证,我知道我可以添加一个属性来指定我的验证,但是有一个选项可以设置一个工厂来自动化所有验证,我看着:此答案,并使用简单的注入器3.1提出了这个问题:

I am trying to automate the validation of my view models, I know I can just add a an attribute to specify my validation but there is an option to set up a factory to automate all that, I looked at: this answer and came up with this using 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;
        }
    }

然后视图模型可以是类似的

Then the view model can be something like

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

但是实现变量始终为null,我也尝试过RegisterCollection但仍然存在相同的问题,当验证器继承自AbstractValidator时,似乎简单的注入器不知道如何解析IValidator(这是实现IValidator的类)

However the implementation variable is always null, I've also tried RegisterCollection but still have the same issue, seems like simple injector does not know how to resolve IValidator when the validator inherits from AbstractValidator(This is the class that implements IValidator)

推荐答案

在Simple Injector中注册Fluent验证工厂,如下所示:

Register the Fluent Validation Factory in Simple Injector like this:

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

然后在合成根目录"中将其注册为ASP.NET MVC:

And then in your Composition Root register it for 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;
    }
);

FluentValidation.MVC集成包中可以找到FluentValidationModelValidatorProvider.记住要为您正在运行的MVC版本获取一个.

The FluentValidationModelValidatorProvider is found in the FluentValidation.MVC integration package. Remember to get the one for the version of MVC you are running.

更新

您可以为没有验证器的对象注册一个空的验证器,例如:

You can register an empty validator for the object that does not have an validator like:

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

这篇关于SimpleInjector和FluentValidationFactory的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-24 00:57