-
Notifications
You must be signed in to change notification settings - Fork 6.1k
Description
Description
The behavior of GetKeyedService() and GetKeyedServices() methods in the Microsoft.Extensions.DependencyInjection library has been updated to address inconsistencies in handling the AnyKey registration. Specifically:
- Behavioral Change: The
GetKeyedService()method now throws an exception when attempting to resolve a single service usingKeyedService.AnyKeyas the lookup key. - Behavioral Change: The
GetKeyedServices()method no longer returnsAnyKeyregistrations when queried withKeyedService.AnyKey.
These changes were introduced to improve consistency in the behavior of keyed service resolution and align with the intended semantics of KeyedService.AnyKey.
Version
.NET 10 Preview 3
Previous behavior
-
GetKeyedService(KeyedService.AnyKey):- Previously, calling
GetKeyedService()withKeyedService.AnyKeywould return a service registration associated withAnyKey. This behavior was inconsistent with the intended semantics, asAnyKeyis meant to represent a special case of keyed services rather than a specific registration.
- Previously, calling
-
GetKeyedServices(KeyedService.AnyKey):- Previously, calling
GetKeyedServices()withKeyedService.AnyKeywould return all registrations forAnyKey. This behavior was inconsistent with the intended semantics, asAnyKeyis not meant to enumerate all keyed services.
- Previously, calling
New behavior
-
GetKeyedService(KeyedService.AnyKey):- Calling
GetKeyedService()withKeyedService.AnyKeynow throws an exception. This ensures thatAnyKeycannot be used to resolve a single service, as it is intended to represent a special case rather than a specific key.
Example:
var service = serviceProvider.GetKeyedService(typeof(IMyService), KeyedService.AnyKey); // Throws InvalidOperationException: "Cannot resolve a single service using AnyKey."
- Calling
-
GetKeyedServices(KeyedService.AnyKey):- Calling
GetKeyedServices()withKeyedService.AnyKeyno longer returns registrations forAnyKey. Instead, it adheres to the updated semantics whereAnyKeyis treated as a special case and does not enumerate services.
Example:
var services = serviceProvider.GetKeyedServices(typeof(IMyService), KeyedService.AnyKey); // Returns an empty collection.
- Calling
Type of breaking change
- Binary incompatible: Existing binaries might encounter a breaking change in behavior, such as failure to load or execute, and if so, require recompilation.
- Source incompatible: When recompiled using the new SDK or component or targeting the new runtime, existing source code might require source changes to compile successfully.
- Behavioral change: Existing binaries might behave differently at runtime.
Reason for change
The previous behavior of GetKeyedService() and GetKeyedServices() with KeyedService.AnyKey was inconsistent with the intended semantics of AnyKey. The changes were introduced to:
- Ensure that
AnyKeyis treated as a special case and cannot be used to resolve a single service. - Prevent
GetKeyedServices()from returningAnyKeyregistrations when queried withAnyKey.
These updates improve the predictability and correctness of the Microsoft.Extensions.DependencyInjection library's behavior when working with keyed services.
Recommended action
Developers using GetKeyedService() or GetKeyedServices() with KeyedService.AnyKey should review their code and update it as follows:
-
For
GetKeyedService(KeyedService.AnyKey):- Replace calls to
GetKeyedService()withKeyedService.AnyKeywith specific keys or alternative logic to handle service resolution.
Before:
var service = serviceProvider.GetKeyedService(typeof(IMyService), KeyedService.AnyKey);
After:
// Replace AnyKey with a specific key or implement custom logic for service resolution. var service = serviceProvider.GetKeyedService(typeof(IMyService), specificKey);
- Replace calls to
-
For
GetKeyedServices(KeyedService.AnyKey):- Update code to explicitly enumerate or query services by specific keys instead of relying on
AnyKey.
Before:
var services = serviceProvider.GetKeyedServices(typeof(IMyService), KeyedService.AnyKey);
After:
// Replace AnyKey with specific keys or implement custom logic for service enumeration. var services = serviceProvider.GetKeyedServices(typeof(IMyService), specificKey);
- Update code to explicitly enumerate or query services by specific keys instead of relying on
Feature area
- Extensions
Affected APIs
Microsoft.Extensions.DependencyInjection.ServiceProvider.GetKeyedService(Type, object)Microsoft.Extensions.DependencyInjection.ServiceProvider.GetKeyedServices(Type, object)
Additional Notes
This change was introduced in .NET 10 Preview 3. Developers targeting earlier versions of .NET are unaffected. For more details, see the pull request and the associated merge commit.
Finally, please email a link to this breaking change issue to .NET Breaking Change Notifications.