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而不是實體,它允許定義一個通用裝飾器,允許對業務邏輯進行驗證。