我正在使用一个基于标准MS DI东西的库(这是我第一次看到,并不熟悉)。到目前为止,还没有什么复杂的事情,我构建了Service Provider:
var services = new ServiceCollection()
.AddSingleton<StartupService>()
.AddSingleton<Service2>()
.AddSingleton<Service3>()
.AddSingleton<Service4>()
.BuildServiceProvider();
然后我通过StartupService启动应用程序
await services.GetService<StartupService>().InitAsync();
然后我通过ctor
在依赖于这些模块的所有模块或其他服务中注入服务:
private readonly Service1 service1;
private readonly Service2 service2;
public OtherService(Service1 s1, Service2 s2)
{
service1 = s1;
service2 = s2;
}
到目前为止,这没什么特别的,但是随着服务数量的增加,其中一些服务需要“热身”,我的StartupService开始显得冷酷:
public async Task InitAsync()
{
Service1.WarmUp();
Service2.WarmUp();
Service3.WarmUp();
...
}
所以我的~~ brilliant ~~愚蠢的想法是实现IWarmUp
接口,并且就像遍历服务收集人员一样:
foreach (var service in services.GetServices<IWarmUp>())
service.WarmUp();
显然没有用。
是否有一个简单的解决方案,而无需构建一些复杂的系统或重写我已经使用注入的所有现有ctors
?如何获得实现特定接口的服务,以便可以使它们完成合同工作?
答案 0 :(得分:0)
您可以将多个实现注册为一种服务类型-请参见here。因此,您可以使用反射来找到实现IWarmUp
的所有类型,然后遍历它们并将每种类型注册到该服务类型。
foreach( var warmUpType in myListOfTypesImplementingIWarmUp )
serviceCollection.AddTransient( typeof(IWarmUp), warmUpType )
然后在InitAsync
中向您的IServiceProvider
询问IEnumerable<IWarmUp>
,并循环调用每个对象上的WarmUp
。
您仍然可以像AddSingleton<Service2>()
一样针对自己注册每种类型,然后像当前一样向DI提出请求。