库 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 使用特定密钥的调用,或更新逻辑以仅枚举要检索的服务。