Eu tenho serviços derivados da mesma interface.
public interface IService { }
public class ServiceA : IService { }
public class ServiceB : IService { }
public class ServiceC : IService { }
Normalmente, outros contêineres IoC como Unity
permitem registrar implementações concretas por algumas Key
que as distinguem.
No ASP.NET Core, como faço para registrar esses serviços e resolvê-los em tempo de execução com base em alguma chave?
Não vejo nenhum Add
método de serviço que aceite um parâmetro key
ou name
, que normalmente seria usado para distinguir a implementação concreta.
public void ConfigureServices(IServiceCollection services)
{
// How do I register services of the same interface?
}
public MyController:Controller
{
public void DoSomething(string key)
{
// How do I resolve the service by key?
}
}
O padrão de fábrica é a única opção aqui?
Atualização1 Analisei
o artigo aqui que mostra como usar o padrão de fábrica para obter instâncias de serviço quando temos várias implementações concretas. No entanto, ainda não é uma solução completa. Quando ligo para o_serviceProvider.GetService()
método, não consigo injetar dados no construtor.
Por exemplo, considere isso:
public class ServiceA : IService
{
private string _efConnectionString;
ServiceA(string efconnectionString)
{
_efConnecttionString = efConnectionString;
}
}
public class ServiceB : IService
{
private string _mongoConnectionString;
public ServiceB(string mongoConnectionString)
{
_mongoConnectionString = mongoConnectionString;
}
}
public class ServiceC : IService
{
private string _someOtherConnectionString
public ServiceC(string someOtherConnectionString)
{
_someOtherConnectionString = someOtherConnectionString;
}
}
Como _serviceProvider.GetService()
injetar a string de conexão apropriada? No Unity, ou em qualquer outra biblioteca de IoC, podemos fazer isso no registro de tipo. No entanto, posso usar a IOption que exigirá que eu injete todas as configurações. Não consigo injetar uma sequência de conexão específica no serviço.
Observe também que estou tentando evitar o uso de outros contêineres (incluindo o Unity), porque também tenho que registrar todo o resto (por exemplo, controladores) no novo contêiner.
Além disso, o uso do padrão de fábrica para criar instâncias de serviço é contra o DIP, pois aumenta o número de dependências que um cliente possui. detalhes aqui .
Então, acho que o DI padrão no ASP.NET Core está faltando duas coisas:
- A capacidade de registrar instâncias usando uma chave
- A capacidade de injetar dados estáticos nos construtores durante o registro
Update1
ser movido para uma pergunta diferente, pois injetar coisas nos construtores é muito diferente de descobrir qual objeto construir