Tengo servicios que se derivan de la misma interfaz.
public interface IService { }
public class ServiceA : IService { }
public class ServiceB : IService { }
public class ServiceC : IService { }
Por lo general, otros contenedores IoC como le Unity
permiten registrar implementaciones concretas por parte de algunos Key
que los distinguen.
En ASP.NET Core, ¿cómo registro estos servicios y los resuelvo en tiempo de ejecución en función de alguna clave?
No veo ningún Add
método de servicio que tome un parámetro key
o name
, que normalmente se usaría para distinguir la implementación 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?
}
}
¿Es el patrón Factory la única opción aquí?
Actualización1
He leído el artículo aquí que muestra cómo usar el patrón de fábrica para obtener instancias de servicio cuando tenemos múltiples implementaciones concretas. Sin embargo, todavía no es una solución completa. Cuando llamo al _serviceProvider.GetService()
método, no puedo inyectar datos en el constructor.
Por ejemplo considere esto:
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;
}
}
¿Cómo se puede _serviceProvider.GetService()
inyectar la cadena de conexión adecuada? En Unity, o en cualquier otra biblioteca de IoC, podemos hacerlo al registrar el tipo. Sin embargo, puedo usar IOption , que requerirá que inyecte todas las configuraciones. No puedo inyectar una cadena de conexión particular en el servicio.
También tenga en cuenta que estoy tratando de evitar el uso de otros contenedores (incluido Unity) porque entonces también tengo que registrar todo lo demás (por ejemplo, Controladores) con el nuevo contenedor.
Además, el uso del patrón de fábrica para crear instancias de servicio va en contra de DIP, ya que aumenta el número de dependencias que un cliente tiene detalles aquí .
Por lo tanto, creo que el DI predeterminado en ASP.NET Core falta dos cosas:
- La capacidad de registrar instancias usando una clave
- La capacidad de inyectar datos estáticos en constructores durante el registro
Update1
puede mover a una pregunta diferente, ya que inyectar cosas en los constructores es muy diferente de calcular qué objeto construir