Domanda

Ricevo un 'errore di non registrato' durante l'esecuzione nella chiamata ValidatorFactory.CreateInstance. Sembra che il tipo viene inviato al metodo è corretto.

Il mio codice di registrazione:

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

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

La mia vista del modello e validatore di codice:

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

La mia ipotesi migliore è che sto registrando il torto validatori.

È stato utile?

Soluzione 3

Registrazione attuale Codice:

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

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

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

Lo stesso errore all'interno CreateInstance:

Il servizio richiesto 'FluentValidation.IValidator`1 [.EmployeeViewModel] (FluentValidation.IValidator)' non è stato registrato.

Altri suggerimenti

Per risolvere da più classi che implementano IValidator, spettacoli il autofac documentazione un paio di tecniche. Non credo che è possibile utilizzare il montaggio con la scansione di questi metodi; avrete registrare i validatori singolarmente.

Per nome

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

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

Per chiave

Gli spettacoli di documentazione un'enumerazione utilizzati come una chiave, ma è possibile utilizzare il tipo come la chiave, che avrebbe permesso di chiamare Resolve utilizzando il validatorType essere passato a voi nel metodo CreateInstance.

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

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

Nota: La documentazione è per la versione 2.3 di Autofac. Sto utilizzando 2.2.4, che è il motivo per cui i nomi dei metodi sopra variano dalla documentazione.

Spero che questo aiuti.

L'altra risposta da @adrift è un bel approccio pulito. Giusto per aggiungere alcune note, questo funziona anche con il tipo di relazione IIndex<K,V>, che Autofac fornisce automaticamente, per esempio:.

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 : non utilizzare IContainerProvider e ApplicationContainer in un componente-invece uso IComponentContext o IIndex<K,V> come sopra. Questo aiuto consentirà di evitare problemi di vita (il vostro esempio associa validatori con l'applicazione, piuttosto che la durata richiesta.)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top