Вопрос

Я получаю «не зарегистрированную ошибку» во время выполнения в вызове 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());

Мой кормиорный процесс:

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

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

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

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

Текущий вариаторФство:

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:

Запрашиваемая услуга «FreentValidation.ivaliDator» [.employeeviewModel] (FreentValidation.ivalidator) 'не зарегистрирована.

Другие советы

Разрешить из нескольких классов, которые реализуют 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, поэтому имена методов выше варьируются от документации.

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top