Para registrar algum serviço em relação à interface e à implementação:
services.AddSingleton<IFoo, Foo>();
services.AddSingleton<Foo>(x => x.GetRequiredService<IFoo>());
Isso garante que seja possível resolver ambos IFoo
e Foo
, e que o contêiner forneceria a mesma instância .
Estou tentando estender esse conceito ao meu caso de uso:
Eu escrevi uma biblioteca que executa uma varredura de assembly na inicialização e registra automaticamente tipos que implementam IAnalyser
. No código do cliente, quero resolver ambos IEnumerable<IAnalyser>
e FooAnalyser
.
Não tenho certeza de como realizar os registros. Isto é o que tenho até agora:
IEnumerable<Type> implementationTypes = ScanClientAssembliesForImplementationsOfIAnalyser();
foreach (var implementationType in implementationTypes)
{
services.AddSingleton(typeof(IAnalyser), implementationType); // (1) works
//services.AddSingleton(implementationType); // (2) incorrect
services.AddSingleton(x => /* ...?... */); // (3)
}
O registro em (1) corretamente me permite resolver IEnumerable<IAnalyser>
.
O registro em (2) me permite resolver FooAnalyser
, mas seria uma instância diferente e, portanto, está incorreto.
Acho que a abordagem correta é registrar a mesma instância por meio de uma fábrica. Como faço isso em (3)?
(Observe que minha abordagem acima pode estar errada. Tudo o que quero é resolver ambos IEnumerable<IAnalyser>
e FooAnalyser
, no código do cliente. Talvez haja uma maneira completamente diferente de fazer isso?)
Encontrei uma solução mais fácil.
Há uma coisa boa: quando você registra a implementação para a interface, você sempre pode (imediatamente) resolver
IEnumerable<interface>
obter todas as implementações registradas.Dito isso, poderíamos simplesmente percorrer todos os tipos, registrando-os como singleton para o tipo e registrá-los como implementação de interface usando o método de fábrica, como abaixo:
Tenho uma configuração de exemplo:
E então resolução (com APIs mínimas, mas isso também funciona com controladores):
Encontrei uma solução alternativa, mas não gostei:
Parece muito caro fazer isso para cada resolução. (Mas admito que, se houvesse alguma maneira integrada de fazer o que eu quero, provavelmente faria algo parecido.)
Se você encontrar um erro na minha abordagem, por favor, me avise. Se houver uma maneira melhor, por favor, adicione sua resposta e eu a aceitarei.