You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET 8中如何从IServiceProvider获取指定类型的所有实现(含键控服务)

解决方案

为什么默认GetServices<T>只返回非键控服务

.NET 8新增的键控服务与传统非键控服务在DI容器中是分开管理的:

  • 传统的GetServices<T>()方法为了向后兼容,仅返回**键为ServiceProvider.DefaultKey(即null)**的非键控服务实例
  • 显式注册的带键服务需要通过键控服务专属方法获取

快速解决:使用GetKeyedServices<T>()

直接调用GetKeyedServices<T>()方法即可获取包括非键控在内的所有服务实例(非键控服务会被视为键为null的键控服务):

var implementations = serviceProvider.GetKeyedServices<ITestInterface>();
// 此时implementations会包含TestClass1、TestClass2、TestClass3三个实例
Assert.True(implementations.Count() == 3); // 断言通过

自定义扩展方法(按需使用)

如果你需要统一封装获取所有服务的逻辑,可以创建一个扩展方法,简化调用流程:

public static class ServiceProviderExtensions
{
    public static IEnumerable<T> GetAllServices<T>(this IServiceProvider provider)
    {
        // GetKeyedServices已包含非键控(键为null)的实例
        return provider.GetKeyedServices<T>();
    }
}

使用方式:

var allImplementations = serviceProvider.GetAllServices<ITestInterface>();
Assert.True(allImplementations.Count() == 3);

关于预期行为的说明

你的预期是合理的——当注册了同一接口的键控和非键控实现时,理应能获取到所有实例。.NET DI通过GetKeyedServices<T>()提供了这个能力,而GetServices<T>()保持原有行为是为了避免破坏依赖旧逻辑的代码。

内容的提问来源于stack exchange,提问作者Grofit

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 08:13:13