2010-10-13 2 views
0

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

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

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

Мое предположение, что я регистрируя валидаторы ошибочны.

ответ

0

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

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

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

Текущий ValidatorFactory:

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)' не имеет т.

+0

в вашей регистрации, я считаю, что это должно быть 'typeof (EmployeeViewModelValidator)', поскольку это будет тип, переданный в 'CreateInstance' –

1

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

По имени

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

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

По Key

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

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

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

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

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

+0

Причина изменения имени отражена в этом сценарии - 'Resolve (validatorType)' вводит в заблуждение, поскольку 'validatorType' является ключом, а не типом сервиса. Следовательно, в 2.3 это 'ResolveKeyed (validatorType)' :) ... хороший ответ! –

+0

@Nicholas Blumhardt, спасибо и спасибо за Autofac :) –

+0

Спасибо за ответ! См. Мои ниже все еще ошибки. – Mike

1

Другой ответ от @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> как указано выше. Это поможет предотвратить проблемы в течение жизни (ваш пример связывает валидаторы с приложением, а не срок службы запроса.)

+0

Спасибо за ответ! См. Мои ниже все еще ошибки. – Mike

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