繁体   English   中英

如何在ASP.NET Web-API项目中将FluentValidation与LightInject一起使用

[英]How to use FluentValidation with LightInject in asp.net web-api project

我试图将使用IoC容器的服务注入到Validation类中。 请参阅以下示例:

[Validator(typeof(UserPayloadValidator))]
public class UserPayload
{
    public int UserId { get; set; }
}

public class UserPayloadValidator : AbstractValidator<UserPayload>
{
    private IUserService _userService;

    public UserPayloadValidator(IUserService userService)
    {
        _userService = userService;

        RuleFor(x => x.UserId).Must(BeUnique).WithMessage("This user already exists");
    }

    private bool BeUnique(int userId)
    {
        var user = _userService.GetUser(userId);

        return user == null;
    }
}

在这一点上,我希望一切都能自动神奇地工作,并将userService注入到验证类中。 相反,我遇到了一个异常,抱怨找不到一个无参数的构造函数。

一些经过reasearch我试图创建一个ValidationFactory作为链接的例子。

public class LightInjectValidationFactory : ValidatorFactoryBase
{
    private readonly ServiceContainer _serviceContainer;

    public LightInjectValidationFactory(ServiceContainer serviceContainer)
    {
        _serviceContainer = serviceContainer;
    }

    public override IValidator CreateInstance(Type validatorType)
    {
        return _serviceContainer.TryGetInstance(validatorType) as IValidator;
    }   
}

并在LightInject配置中

//Set up fluent validation
FluentValidationModelValidatorProvider.Configure(httpConfiguration, provider =>
{
    provider.ValidatorFactory = new LightInjectValidationFactory(container);
});

这将导致异常:无法解析类型:FluentValidation.IValidator`1

我想IoC容器不知道如何为验证程序解析正确的实例。

任何想法都非常感谢。

感谢上面的评论,我意识到我实际上并没有在容器中注册验证器。 对于所有验证器,可以这样做:

FluentValidation.AssemblyScanner.FindValidatorsInAssemblyContaining<UserPayloadValidator>()
            .ForEach(result =>
            {
                container.Register(result.InterfaceType, result.ValidatorType);
            });

请注意, UserPayloadValidator需要只是您的验证之一 基于此类型,FindValidatorsInAssembly可以推断所有其他可用的验证器。

另外,在验证工厂中,如果工厂尝试实例化不存在的验证器(控制器中不存在验证器的参数),则应使用TryGetInstance而不是GetInstance。

我发现所有验证类的解决方案都使用注入服务。

替换下面的代码

FluentValidation.AssemblyScanner.FindValidatorsInAssemblyContaining<UserPayloadValidator>()
            .ForEach(result =>
            {
                container.Register(result.InterfaceType, result.ValidatorType);
            });

FluentValidation.AssemblyScanner findValidatorsInAssembly = FluentValidation.AssemblyScanner.FindValidatorsInAssembly(typeof(UserPayloadValidator).Assembly);
            foreach (FluentValidation.AssemblyScanner.AssemblyScanResult item in findValidatorsInAssembly)
            {
                container.Register(item.InterfaceType, item.ValidatorType);
            }

使用此方法,所有验证器类都使用注入服务。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM