我有从同一接口派生的服务。
public interface IService { }
public class ServiceA : IService { }
public class ServiceB : IService { }
public class ServiceC : IService { }
通常,其他 IoC 容器如Unity
允许您注册一些具体的实现Key
这使他们与众不同。
在 ASP.NET Core 中,如何注册这些服务并在运行时根据某个密钥解析它们?
我没有看到任何Add
服务方法key
or name
参数,通常用于区分具体实现。
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?
}
}
工厂模式是这里唯一的选择吗?
Update1
我已经浏览了这篇文章here这展示了当我们有多个具体实现时如何使用工厂模式来获取服务实例。然而,它仍然不是一个完整的解决方案。当我打电话给_serviceProvider.GetService()
方法,我无法将数据注入构造函数。
例如考虑这个:
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;
}
}
How can _serviceProvider.GetService()
注入适当的连接字符串?
在 Unity 或任何其他 IoC 库中,我们可以在类型注册时执行此操作。我可以用IOption但是,这需要我注入所有设置。我无法将特定的连接字符串注入到服务中。
另请注意,我试图避免使用其他容器(包括 Unity),因为这样我还必须使用新容器注册其他所有内容(例如控制器)。
此外,使用工厂模式创建服务实例也不符合 DIP,因为它会增加客户端的依赖项数量详细信息在这里.
所以,我认为 ASP.NET Core 中的默认 DI 缺少两件事:
- 使用密钥注册实例的能力
- 能够在注册期间将静态数据注入构造函数