如何确定在标准MS DI中实现接口X的服务的范围?

时间:2018-08-16 09:21:25

标签: c# dependency-injection interface

我正在使用一个基于标准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?如何获得实现特定接口的服务,以便可以使它们完成合同工作?

1 个答案:

答案 0 :(得分:0)

您可以将多个实现注册为一种服务类型-请参见here。因此,您可以使用反射来找到实现IWarmUp的所有类型,然后遍历它们并将每种类型注册到该服务类型。

foreach( var warmUpType in myListOfTypesImplementingIWarmUp )
    serviceCollection.AddTransient( typeof(IWarmUp), warmUpType )

然后在InitAsync中向您的IServiceProvider询问IEnumerable<IWarmUp>,并循环调用每个对象上的WarmUp

您仍然可以像AddSingleton<Service2>()一样针对自己注册每种类型,然后像当前一样向DI提出请求。