使用 AnyKey 修复 GetKeyedService() 和 GetKeyedServices() 中的问题

Microsoft.Extensions.DependencyInjection 中的 GetKeyedService(IServiceProvider, Type, Object)GetKeyedServices(IServiceProvider, Type, Object) 方法行为已更新,以解决处理 KeyedService.AnyKey 注册时出现的不一致问题。 具体而言,当你尝试使用KeyedService.AnyKey作为查找键解析单个服务时,GetKeyedService()现在会抛出一个异常,并且查询KeyedService.AnyKey时,GetKeyedServices()(复数)不再返回AnyKey的注册信息。

引入的版本

.NET 10

以前的行为

以前,调用 GetKeyedService()KeyedService.AnyKey 时,会返回一个与 AnyKey 相关的服务注册。 此行为与预期语义不一致,这意味着 AnyKey 表示键式服务的特殊情况,而不是特定注册。

调用 GetKeyedServices()KeyedService.AnyKey 返回了 AnyKey 的所有注册。 此行为也与预期语义不一致,因为 AnyKey 的设计目的不是枚举所有已键控服务。

新行为

从 .NET 10 开始,调用 GetKeyedService() 时,KeyedService.AnyKey 会引发 InvalidOperationException。 这可确保 AnyKey 不能用于解析单个服务,因为它旨在表示特殊情况而不是特定密钥。

var service = serviceProvider.GetKeyedService(typeof(IMyService), KeyedService.AnyKey);
// Throws InvalidOperationException: "Cannot resolve a single service using AnyKey."

此外,调用 GetKeyedServices()KeyedService.AnyKey 后,将不再返回 AnyKey 的注册信息。 相反,它遵循更新的语义,其中 AnyKey 被视为特殊情况,并且不枚举服务。

var services = serviceProvider.GetKeyedServices(typeof(IMyService), KeyedService.AnyKey);
// Returns an empty collection.

破坏性变更的类型

此更改为行为更改

更改原因

以前GetKeyedService()GetKeyedServices()KeyedService.AnyKey的行为与AnyKey的预期语义不一致。 这些更改是为了确保AnyKey被视为特殊情况,不能用于解析单个服务,并且防止GetKeyedServices()在使用AnyKey查询时返回AnyKey注册。 这些更新提高了库在使用键控服务时行为的可预测性和正确性 Microsoft.Extensions.DependencyInjection 。 如需更多详细信息,请参阅 拉取请求 和相关的 合并提交

如果使用 GetKeyedService()GetKeyedServices()KeyedService.AnyKey 一起使用,请查看代码并将其更新为使用特定键,而不是使用 AnyKey

对于 GetKeyedService(KeyedService.AnyKey),请将 GetKeyedService() 的调用替换为 KeyedService.AnyKey,并使用特定密钥或替代逻辑来处理服务解析。

对于 GetKeyedServices(KeyedService.AnyKey),请将对 GetKeyedServices() 调用替换为 KeyedService.AnyKey 使用特定密钥的调用,或更新逻辑以仅枚举要检索的服务。

受影响的 API