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

.NET 8中如何获取键控服务类型的所有实例?

.NET 8键控服务中获取所有实例的等价实现

在.NET 8的键控服务体系中,直接注入IEnumerable<IProduct>无法获取到已注册的键控服务实例,你可以通过以下几种方式实现等价效果:

方式一:使用KeyedService<T>集合注入

通过注入IEnumerable<KeyedService<IProduct>>,可以直接获取到所有带键的服务条目,再从中提取服务实例:
ProductsManager.cs

public class ProductsManager
{
    public ProductsManager(IEnumerable<KeyedService<IProduct>> keyedProducts)
    {
        // 提取所有键控服务实例
        List<IProduct> allProducts = keyedProducts.Select(k => k.Service).ToList();
        // allProducts.Count = 2
    }
}

这个方式无需额外修改服务注册代码,直接利用框架提供的KeyedService<T>类型即可。

方式二:手动注册全局实例集合

如果希望继续保持原有IEnumerable<IProduct>的注入方式,可以在服务注册时手动构建这个集合:
Program.cs

builder.Services.AddKeyedSingleton<IProduct, Product1>("p1");
builder.Services.AddKeyedSingleton<IProduct, Product2>("p2");

// 注册包含所有键控服务的IEnumerable<IProduct>
builder.Services.AddSingleton<IEnumerable<IProduct>>(serviceProvider =>
{
    // 列出所有键控服务的键
    string[] serviceKeys = { "p1", "p2" };
    return serviceKeys.Select(key => serviceProvider.GetRequiredKeyedService<IProduct>(key)).ToList();
});

之后ProductsManager的原有构造函数就能正常获取到2个实例。

方式三:通过IServiceProvider手动获取(不推荐)

直接注入IServiceProvider后,根据已知的键逐个获取实例:
ProductsManager.cs

public class ProductsManager
{
    public ProductsManager(IServiceProvider serviceProvider)
    {
        IProduct product1 = serviceProvider.GetRequiredKeyedService<IProduct>("p1");
        IProduct product2 = serviceProvider.GetRequiredKeyedService<IProduct>("p2");
        List<IProduct> allProducts = new List<IProduct> { product1, product2 };
    }
}

这种方式需要硬编码服务键,灵活性较差,不符合依赖注入的显式依赖原则,仅作为临时方案使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 06:42:12