Autofac с FluentValidation в MVC2 - PullRequest
       36

Autofac с FluentValidation в MVC2

0 голосов
/ 13 октября 2010

Я получаю «незарегистрированную ошибку» во время выполнения в вызове ValidatorFactory.CreateInstance.Похоже, тип, отправляемый в метод, является правильным.

Мой регистрационный код:

...
builder.RegisterAssemblyTypes(assembly).Where(t => t.Name.EndsWith("Validator")).As<IValidator>();
builder.Register(d => _containerProvider).As<IContainerProvider>();
builder.Register(d => new ValidatorFactory(_containerProvider.ApplicationContainer.Resolve<IContainerProvider>())).As<IValidatorFactory>();

_containerProvider = new ContainerProvider(builder.Build());

Мой код ValidatorFactory:

public class ValidatorFactory : ValidatorFactoryBase {
    private readonly IContainerProvider _containerProvider;

    public ValidatorFactory(IContainerProvider containerProvider) {
        _containerProvider = containerProvider;
    }

    public override IValidator CreateInstance(Type validatorType) {
        return _containerProvider.ApplicationContainer.Resolve<IValidator>(validatorType);
    }
}

Мой вид модели и код проверки:

[Validator(typeof(EmployeeViewModelValidator))]
public class EmployeeViewModel {
    public EmployeeViewModel() {}
    public EmployeeViewModel(string firstName) {
        FirstName = firstName;
    }

    public string FirstName { get; private set; }
}

public class EmployeeViewModelValidator : AbstractValidator<EmployeeViewModel> {
    public EmployeeViewModelValidator() {
        RuleFor(x => x.FirstName)
            .NotEmpty();
    }
}

Мой лучшийЯ предполагаю, что я неправильно регистрирую валидаторы.

Ответы [ 3 ]

1 голос
/ 14 октября 2010

Другой ответ @adrift - хороший, чистый подход.Просто для добавления некоторых заметок это также работает с типом отношений IIndex<K,V>, который Autofac предоставляет автоматически, например:

public class ValidatorFactory : ValidatorFactoryBase {
    readonly IIndex<Type, IValidator> _validators;

    public ValidatorFactory(IIndex<Type, IValidator> validators) {
        _validators = validators;
    }

    public override IValidator CreateInstance(Type validatorType) {
        return _validators[validatorType];
    }
}

Важное примечание : не используйте IContainerProvider иApplicationContainer в компоненте - вместо этого используйте IComponentContext или IIndex<K,V>, как указано выше.Это поможет предотвратить проблемы времени жизни (ваш пример связывает валидаторы с приложением, а не время жизни запроса.)

1 голос
/ 13 октября 2010

Чтобы разрешить из нескольких классов, которые реализуют IValidator, документация autofac показывает несколько методов.Я не думаю, что вы можете использовать сканирование сборки с этими методами;вы должны будете зарегистрировать валидаторы индивидуально.

По имени

builder.RegisterType<EmployeeViewModelValidator>().Named<IValidator>("employee");

var r = container.Resolve<IValidator>("employee");

По ключу

В документации приведенперечисление используется в качестве ключа, но вы можете использовать тип в качестве ключа, что позволит вам вызывать Resolve, используя validatorType, передаваемый вам в методе CreateInstance.

builder.RegisterType<EmployeeViewModelValidator>().Keyed<IValidator>(typeof(EmployeeViewModelValidator));    

var r = container.Resolve<IValidator>(validatorType);

Примечание: документация для версии 2.3 Autofac.Я использую 2.2.4, поэтому приведенные выше имена методов отличаются от документации.

Надеюсь, это поможет.

0 голосов
/ 14 октября 2010

Текущий регистрационный код:

builder.RegisterType<EmployeeViewModelValidator>().Keyed<IValidator>(typeof(EmployeeViewModel));
builder.RegisterType<ValidatorFactory>().As<IValidatorFactory>();

_containerProvider = new ContainerProvider(builder.Build());

Текущий завод Validator:

public class ValidatorFactory : ValidatorFactoryBase {
    readonly IIndex<Type, IValidator> _validators; 

    public ValidatorFactory(IIndex<Type, IValidator> validators) {
        _validators = validators;
    } 

    public override IValidator CreateInstance(Type validatorType) {
        return _validators[validatorType];
    }
}

Та же ошибка внутри CreateInstance:

Запрошенный сервис 'FluentValidation.IValidator`1 [.EmployeeViewModel] (FluentValidation.IValidator) 'не зарегистрирован.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...