Pregunta

Me estoy poniendo un 'error no registrado' durante la ejecución de la llamada ValidatorFactory.CreateInstance. Parece que el tipo de ser enviado en el método es correcto.

Mi código de registro:

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

Mi código 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);
    }
}

Mi modelo de vista y validador de código:

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

Mi mejor conjetura es que estoy registrando el mal validadores.

¿Fue útil?

Solución 3

Registro actual Código:

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

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

ValidatorFactory actual:

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

mismo error en el interior CreateInstance:

El servicio solicitado 'FluentValidation.IValidator`1 [.EmployeeViewModel] (FluentValidation.IValidator)' no ha sido registrada.

Otros consejos

Para resolver a partir de múltiples clases que implementan IValidator, muestra el autofac documentación una par de técnicas. No creo que se puede utilizar conjunto de escaneado con estos métodos; que tendrá registrar los validadores de forma individual.

Por nombre

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

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

Por Tecla

Los espectáculos de documentación una enumeración siendo utilizados como una llave, pero se puede utilizar el tipo como la clave, lo que le permiten hablar con el Resolve validatorType se pasa a usted en el método CreateInstance.

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

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

Nota: La documentación es para la versión 2.3 de Autofac. Estoy usando 2.2.4, por lo que los nombres de los métodos anteriormente varían de la documentación.

Espero que esto ayude.

La otra respuesta por @adrift es un enfoque limpio agradable. Sólo para añadir algunas notas, esto también funciona con el tipo de relación IIndex<K,V>, que Autofac proporciona de forma automática, por ejemplo:.

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

Nota importante: : no utilice IContainerProvider y ApplicationContainer en un uso IComponentContext componente lugar o IIndex<K,V> que el anterior. Esto ayuda a prevenir problemas de la voluntad de toda la vida (sus asociados ejemplo validadores con la aplicación en lugar de la solicitud de toda la vida.)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top