From a7e45aca085a3211db4b8919afec3c44be75c7c6 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 29 Sep 2025 17:09:43 +0000 Subject: [PATCH 1/4] Initial plan From 85316d12af1f035a6bedbf4e0e2e9a4352219492 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 29 Sep 2025 17:15:17 +0000 Subject: [PATCH 2/4] Add breaking change documentation for FromKeyedServicesAttribute.Key nullability Co-authored-by: gewarren <24882762+gewarren@users.noreply.github.com> --- docs/core/compatibility/8.0.md | 1 + ...fromkeyedservicesattribute-key-nullable.md | 57 +++++++++++++++++++ docs/core/compatibility/toc.yml | 2 + 3 files changed, 60 insertions(+) create mode 100644 docs/core/compatibility/extensions/8.0/fromkeyedservicesattribute-key-nullable.md diff --git a/docs/core/compatibility/8.0.md b/docs/core/compatibility/8.0.md index 6c56c864ba3aa..5f9da27691430 100644 --- a/docs/core/compatibility/8.0.md +++ b/docs/core/compatibility/8.0.md @@ -90,6 +90,7 @@ If you're migrating an app to .NET 8, the breaking changes listed here might aff | [ConfigurationManager package no longer references System.Security.Permissions](extensions/8.0/configurationmanager-package.md) | Source incompatible | | [DirectoryServices package no longer references System.Security.Permissions](extensions/8.0/directoryservices-package.md) | Source incompatible | | [Empty keys added to dictionary by configuration binder](extensions/8.0/dictionary-configuration-binding.md) | Behavioral change | +| [FromKeyedServicesAttribute.Key may be null](extensions/8.0/fromkeyedservicesattribute-key-nullable.md) | Source incompatible | | [HostApplicationBuilderSettings.Args respected by HostApplicationBuilder ctor](extensions/8.0/hostapplicationbuilder-ctor.md) | Behavioral change | | [ManagementDateTimeConverter.ToDateTime returns a local time](extensions/8.0/dmtf-todatetime.md) | Behavioral change | | [System.Formats.Cbor DateTimeOffset formatting change](extensions/8.0/cbor-datetime.md) | Behavioral change | diff --git a/docs/core/compatibility/extensions/8.0/fromkeyedservicesattribute-key-nullable.md b/docs/core/compatibility/extensions/8.0/fromkeyedservicesattribute-key-nullable.md new file mode 100644 index 0000000000000..3fdec0854351e --- /dev/null +++ b/docs/core/compatibility/extensions/8.0/fromkeyedservicesattribute-key-nullable.md @@ -0,0 +1,57 @@ +--- +title: "Breaking change: FromKeyedServicesAttribute.Key may be null" +description: "Learn about the breaking change in .NET 8 where FromKeyedServicesAttribute.Key is now nullable to support unkeyed services and inheritance." +ms.date: 01/08/2025 +ai-usage: ai-assisted +ms.custom: https://dev.azure.com/msft-skilling/Content/_workitems/edit/486863 +--- + +# FromKeyedServicesAttribute.Key may be null + + has been changed from a non-nullable `object` to a nullable `object?` to support null values for unkeyed services and inheritance scenarios. + +## Version introduced + +.NET 8 + +## Previous behavior + + was declared as a non-nullable `object`: + +```csharp +public object Key { get; } +``` + +## New behavior + + is now declared as a nullable `object?`: + +```csharp +public object? Key { get; } +``` + +A `null` value indicates there is no key and only the parameter type is used to resolve the service. This is useful for dependency injection implementations that require an explicit way to declare that the parameter should be resolved for unkeyed services. A `null` value is also used with inheritance scenarios to indicate that the key should be inherited from the parent scope. + +## Type of breaking change + +This change can affect [source compatibility](../../categories.md#source-compatibility). + +## Reason for change + +Support was added for keyed services to annotate parameters as unkeyed. This allows developers to explicitly indicate when a parameter should be resolved without a key, which is particularly useful in scenarios where both keyed and unkeyed services are registered for the same type. + +## Recommended action + +Adjust any code that uses to handle `null` values. For example: + +```csharp +// Before - assuming Key is never null +var keyValue = attribute.Key.ToString(); + +// After - handling nullable Key +var keyValue = attribute.Key?.ToString() ?? "unkeyed"; +``` + +## Affected APIs + +- \ No newline at end of file diff --git a/docs/core/compatibility/toc.yml b/docs/core/compatibility/toc.yml index 33939a4065721..4fb53f4b04870 100644 --- a/docs/core/compatibility/toc.yml +++ b/docs/core/compatibility/toc.yml @@ -434,6 +434,8 @@ items: href: extensions/8.0/directoryservices-package.md - name: Empty keys added to dictionary by configuration binder href: extensions/8.0/dictionary-configuration-binding.md + - name: FromKeyedServicesAttribute.Key may be null + href: extensions/8.0/fromkeyedservicesattribute-key-nullable.md - name: HostApplicationBuilderSettings.Args respected by constructor href: extensions/8.0/hostapplicationbuilder-ctor.md - name: ManagementDateTimeConverter.ToDateTime returns a local time From 2ca2328a845a19c49a027f97e25fe67f17bc6630 Mon Sep 17 00:00:00 2001 From: Genevieve Warren <24882762+gewarren@users.noreply.github.com> Date: Mon, 29 Sep 2025 13:40:22 -0700 Subject: [PATCH 3/4] human edits --- docs/core/compatibility/8.0.md | 2 +- ...fromkeyedservicesattribute-key-nullable.md | 24 +++++++------------ docs/core/compatibility/toc.yml | 2 +- 3 files changed, 10 insertions(+), 18 deletions(-) diff --git a/docs/core/compatibility/8.0.md b/docs/core/compatibility/8.0.md index 5f9da27691430..15b7c857b2109 100644 --- a/docs/core/compatibility/8.0.md +++ b/docs/core/compatibility/8.0.md @@ -90,7 +90,7 @@ If you're migrating an app to .NET 8, the breaking changes listed here might aff | [ConfigurationManager package no longer references System.Security.Permissions](extensions/8.0/configurationmanager-package.md) | Source incompatible | | [DirectoryServices package no longer references System.Security.Permissions](extensions/8.0/directoryservices-package.md) | Source incompatible | | [Empty keys added to dictionary by configuration binder](extensions/8.0/dictionary-configuration-binding.md) | Behavioral change | -| [FromKeyedServicesAttribute.Key may be null](extensions/8.0/fromkeyedservicesattribute-key-nullable.md) | Source incompatible | +| [FromKeyedServicesAttribute.Key can be null](extensions/8.0/fromkeyedservicesattribute-key-nullable.md) | Source incompatible | | [HostApplicationBuilderSettings.Args respected by HostApplicationBuilder ctor](extensions/8.0/hostapplicationbuilder-ctor.md) | Behavioral change | | [ManagementDateTimeConverter.ToDateTime returns a local time](extensions/8.0/dmtf-todatetime.md) | Behavioral change | | [System.Formats.Cbor DateTimeOffset formatting change](extensions/8.0/cbor-datetime.md) | Behavioral change | diff --git a/docs/core/compatibility/extensions/8.0/fromkeyedservicesattribute-key-nullable.md b/docs/core/compatibility/extensions/8.0/fromkeyedservicesattribute-key-nullable.md index 3fdec0854351e..88cc71af9add8 100644 --- a/docs/core/compatibility/extensions/8.0/fromkeyedservicesattribute-key-nullable.md +++ b/docs/core/compatibility/extensions/8.0/fromkeyedservicesattribute-key-nullable.md @@ -1,12 +1,12 @@ --- -title: "Breaking change: FromKeyedServicesAttribute.Key may be null" +title: "Breaking change: FromKeyedServicesAttribute.Key can be null" description: "Learn about the breaking change in .NET 8 where FromKeyedServicesAttribute.Key is now nullable to support unkeyed services and inheritance." -ms.date: 01/08/2025 +ms.date: 09/29/2025 ai-usage: ai-assisted ms.custom: https://dev.azure.com/msft-skilling/Content/_workitems/edit/486863 --- -# FromKeyedServicesAttribute.Key may be null +# FromKeyedServicesAttribute.Key can be null has been changed from a non-nullable `object` to a nullable `object?` to support null values for unkeyed services and inheritance scenarios. @@ -16,7 +16,7 @@ ms.custom: https://dev.azure.com/msft-skilling/Content/_workitems/edit/486863 ## Previous behavior - was declared as a non-nullable `object`: +Previously, was declared as a non-nullable `object`: ```csharp public object Key { get; } @@ -24,7 +24,7 @@ public object Key { get; } ## New behavior - is now declared as a nullable `object?`: +Starting in .NET 8, is now declared as a nullable `object?`: ```csharp public object? Key { get; } @@ -38,20 +38,12 @@ This change can affect [source compatibility](../../categories.md#source-compati ## Reason for change -Support was added for keyed services to annotate parameters as unkeyed. This allows developers to explicitly indicate when a parameter should be resolved without a key, which is particularly useful in scenarios where both keyed and unkeyed services are registered for the same type. +Support was added for keyed services to annotate parameters as unkeyed. This change allows developers to explicitly indicate when a parameter should be resolved without a key, which is particularly useful in scenarios where both keyed and unkeyed services are registered for the same type. ## Recommended action -Adjust any code that uses to handle `null` values. For example: - -```csharp -// Before - assuming Key is never null -var keyValue = attribute.Key.ToString(); - -// After - handling nullable Key -var keyValue = attribute.Key?.ToString() ?? "unkeyed"; -``` +Adjust any code that uses to handle `null` values. ## Affected APIs -- \ No newline at end of file +- diff --git a/docs/core/compatibility/toc.yml b/docs/core/compatibility/toc.yml index 4fb53f4b04870..2533b4153a347 100644 --- a/docs/core/compatibility/toc.yml +++ b/docs/core/compatibility/toc.yml @@ -434,7 +434,7 @@ items: href: extensions/8.0/directoryservices-package.md - name: Empty keys added to dictionary by configuration binder href: extensions/8.0/dictionary-configuration-binding.md - - name: FromKeyedServicesAttribute.Key may be null + - name: FromKeyedServicesAttribute.Key can be null href: extensions/8.0/fromkeyedservicesattribute-key-nullable.md - name: HostApplicationBuilderSettings.Args respected by constructor href: extensions/8.0/hostapplicationbuilder-ctor.md From 43c7e2edeeaeb4aa1471a3d4cbc48a0ee4d88de3 Mon Sep 17 00:00:00 2001 From: Genevieve Warren <24882762+gewarren@users.noreply.github.com> Date: Mon, 29 Sep 2025 13:43:26 -0700 Subject: [PATCH 4/4] Update docs/core/compatibility/extensions/8.0/fromkeyedservicesattribute-key-nullable.md --- .../extensions/8.0/fromkeyedservicesattribute-key-nullable.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/core/compatibility/extensions/8.0/fromkeyedservicesattribute-key-nullable.md b/docs/core/compatibility/extensions/8.0/fromkeyedservicesattribute-key-nullable.md index 88cc71af9add8..b408b9378898f 100644 --- a/docs/core/compatibility/extensions/8.0/fromkeyedservicesattribute-key-nullable.md +++ b/docs/core/compatibility/extensions/8.0/fromkeyedservicesattribute-key-nullable.md @@ -3,7 +3,6 @@ title: "Breaking change: FromKeyedServicesAttribute.Key can be null" description: "Learn about the breaking change in .NET 8 where FromKeyedServicesAttribute.Key is now nullable to support unkeyed services and inheritance." ms.date: 09/29/2025 ai-usage: ai-assisted -ms.custom: https://dev.azure.com/msft-skilling/Content/_workitems/edit/486863 --- # FromKeyedServicesAttribute.Key can be null