使用简单注入器注册通用验证

时间:2016-03-31 20:57:48

标签: c# inversion-of-control fluentvalidation simple-injector

我想用SimpleInjector注册通用验证(流畅验证)......

这是我到目前为止所做的尝试:
User.cs

public class User
{
    public int Id { get; set; }   
    public string Email { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

UserService.cs

public class UserService : IUserService
{
    private readonly IValidator<User> _userValidator;

    public UserService(IValidator<User> userValidator)
    {
        _userValidator = userValidator;
    }

    public OperationResult Add(User user)
    {
        OperationResult operationResult = new OperationResult();

        ValidationResult validationResult = _userValidator.Validate(user);
        if (!validationResult.IsValid)
        {
            operationResult.IsSuccess = false;

            ValidationFailure firstOrDefaultValidationFailure =
                validationResult.Errors.FirstOrDefault();

            if (firstOrDefaultValidationFailure != null)
            {
                operationResult.Message = firstOrDefaultValidationFailure.ErrorMessage;
            }
        }

        //TODO do your business here...

        return operationResult;
    }
}

IOC:

    Container = new Container();

    // I WANT TO MAKE BELOW LINE GENERIC...
    Container.Register(typeof(IValidator<User>), () => new UserValidator());

    Container.Register<IUserService, UserService>(Lifestyle.Transient);

    Container.Verify();

它现在正在运作。但正如您所看到的,验证器的注册不是通用的。

我试过了;

Container.Register(typeof(IValidator<>), typeof(ValidationContext<>));

它在运行时出错:

  

要使容器能够创建ValidationContext<T>,它应该只有一个公共构造函数:它有2个

我也尝试过:

Container.Register(typeof(IValidator<>), typeof(ValidatorDescriptor<>));

另一个错误:

  

提供的类型ValidatorDescriptor<T>未实现IValidator<T>

最后我试过了:

IValidatorFactory validatorFactory = new AttributedValidatorFactory();
IValidator<User> validator = validatorFactory.GetValidator<User>();

但是它给出了验证器。因为User.cs类没有属性,如;

[Validator(typeof(UserValidator))]

我该怎么做才能解决这个问题?

1 个答案:

答案 0 :(得分:4)

因此,如果我理解正确,您有IValidator<T>的多个非通用实现(例如UserValidatorEmployeeValidatorOrderValidator等,并且您想要注册他们都是。

这是文档here中描述的场景,您基本上有两个选项。

选项1:逐个注册:

container.Register<IValidator<User>, UserValidator>();
container.Register<IValidator<Customer>, CustomerValidator>();
container.Register<IValidator<Employee>, EmployeeValidator>();
container.Register<IValidator<Order>, OrderValidator>();
container.Register<IValidator<Product>, ProductValidator>();
// etc

选项2:使用批量注册:

container.Register(typeof(IValidator<>), new[] { typeof(IValidator<>).Assembly });

这里我们传入一个列表,其中包含Simple Injector用于搜索IValidator<T>的非泛型实现的程序集。在内部,Simple Injector将使用选项1手动进行相同的注册。

请注意,您的服务类与支持验证的代码纠缠在一起。这会导致大量代码重复,增加复杂性并在将来导致维护问题。您应该考虑使用here所述的命令移动到模型。这个模型允许在命令而不是权限上定义valudator,这允许定义一个允许对业务逻辑应用验证的通用装饰器。

相关问题