2

我要注册的通用验证(流利验证)与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<>)); 

它给错误运行时:

For the container to be able to create ValidationContext<T> it should have only one public constructor: it has 2

我也试过:

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

另一个错误:

The supplied type ValidatorDescriptor<T> does not implement IValidator<T>

最后我想:

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

但它提供了空验证器。因为在User.cs类中没有任何属性,例如;

[Validator(typeof(UserValidator))] 

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

回答

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

下面我们通过一个列表与简单的进样器使用程序集搜索非通用实现IValidator<T>。在内部,Simple Injector将进行与我们通过选项1进行手动注册相同的一套注册。

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