1

Я пытаюсь внедрить сервис, используя контейнер IoC, в класс Validation. Смотрите пример ниже:Как использовать FluentValidation с LightInject в проекте asp.net web-api

[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 не знает, как для разрешения правильного экземпляра для валидатора.

Любые идеи очень ценятся.

+0

Как вы регистрируете «IUserService» и «UserPayLoadValidator»? –

+0

Спасибо @YannickMeeus. Похоже, я не регистрировал сервисы валидатора. – Bogdan

ответ

2

Благодаря вышеприведенному комментарию я понял, что на самом деле я не зарегистрировал валидатор в контейнере. Это может быть сделано, как это для всех валидаторов:

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

Пожалуйста, обратите внимание, что UserPayloadValidator должен быть только один ваших валидаторов. Основываясь на этом типе, FindValidatorsInAssembly может вывести все остальные доступные валидаторы.

Кроме того, на заводе проверки следует использовать TryGetInstance вместо GetInstance в случае завод пытается создать экземпляр несуществующих валидаторов (параметр в контроллере, для которого валидаторы не существует)

+0

Отличный @Bogdan, это очень полезно для меня. Еще одна вещь, у меня есть несколько классов Validator, и как я могу использовать все это в свежем инъекции? –

0

я нашел решение для всех проверки классы используют инъекционную услугу.

Заменить ниже код

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

Используя это все ваши классы валидатор использовать впрыскивается службу.

 Смежные вопросы

  • Нет связанных вопросов^_^