Autofac - como resolver Func para ISomething de Singleton onde ISomething é InstancePerHttpRequest
Estou tentando usar o Autofac para injetar dependências no FluentValidation em um aplicativo MVC 4. Eu acho que tenho a estratégia trabalhada, mas eu estou ficando preso com a resolução do meu IS-por-pedido de um singleton.
Aqui está o cenário: Eu tenho um validador que deriva do AbstractValidator do FluentValidation. Eu li que os validadores FluentValidation funcionam melhor como singletons, então meu construtor espera um Func e armazena esse Factory para uso posterior. Quando o validador é usado, ele deve perguntar à fábrica armazenada por um IDataStore, obter a instância criada para essa solicitação e usá-la. Essa é a teoria. Eu quero dar crédito ahttps://github.com/robdmoore/UnobtrusiveMVCTechniques, o que me ajudou a resolver esta solução. Aqui está o validador ...
public class SiteAdminViewModelValidator : AbstractValidator<SiteAdminViewModel> {
private readonly Func<IDataStore> _dbFactory;
public SiteAdminViewModelValidator(Func<IDataStore> dbFactory) {
_dbFactory = dbFactory;
RuleFor(model => model.SiteCode).Length(1, 40).Must(BeSpecial);
}
public bool BeSpecial(string siteCode) {
var db = _dbFactory();
List<Stuff> stuffs = db.All<Stuff>().ToList();
return true;
}
}
Se alguém puder me indicar um exemplo prático do que estou tentando realizar, isso seria ótimo, mas também gostaria de saber a solução para essa peça específica de truques do Autofac.
Aqui está o meu registro de validador ...
public class FluentValidatorModule : Module {
protected override void Load(ContainerBuilder builder) {
base.Load(builder);
builder.RegisterType<AutofacValidatorFactory>().As<IValidatorFactory>().SingleInstance();
var validators = AssemblyScanner.FindValidatorsInAssembly(System.Reflection.Assembly.GetExecutingAssembly());
validators.ToList().ForEach(v => builder.RegisterType(v.ValidatorType).As(v.InterfaceType).SingleInstance());
}
}
Aqui está o meu registro para a fábrica IDataStore ...
builder.RegisterType<SuperDB>().As<IDataStore>().InstancePerHttpRequest();
builder.Register<Func<IDataStore>>(c => {
var context = c.Resolve<IComponentContext>();
return context.Resolve<IDataStore>;
});
Aqui está o erro que estou recebendo quando meu validador pede um IDataStore na linha - var db = _dbFactory ();
Nenhum escopo com uma tag correspondente a 'AutofacWebRequest' é visível no escopo em que a instância foi solicitada. Isso geralmente indica que um componente registrado como solicitação por HTTP está sendo solicitado por um componente SingleInstance () (ou um cenário semelhante). Sob a integração da Web, sempre solicite dependências de DependencyResolver.Current ou ILifetimeScopeProvider.RequestLifetime, nunca do próprio recipiente .
... o que é exatamente o que eu obtive quando tentei antes de escrever meu próprio registro de fábrica - o registro Func. Da leitura de várias respostas a perguntas semelhantes, parecia que o que eu tenho acima deveria funcionar, porque pensei que estava agora resolvendo o Func para obter o resolvedor atual.
Qualquer ajuda será muito apreciada.