.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
相关产品推荐
相关产品推荐

