Skip to content

[Breaking change]: In Dependency Injection, the FromKeyedServicesAttribute will no longer inject a non-keyed parameter #42313

@steveharter

Description

@steveharter

Description

Versions affected: 9.0 RC1 and 8.0.9 servicing.

See dotnet/runtime#102204.

When using the FromKeyedServicesAttribute to specify a keyed service to be injected, an incorrect service may be passed.

Version

Other (please put exact version in description textbox)

Previous behavior

When a keyed service is intended to be injected as a parameter in a service constructor by using the FromKeyedServicesAttribute such as:

public MyService([FromKeyedServices("service1")] IService service1, ...

and the corresponding keyed service ("service1" in this example) was not registered as a keyed service but was registered as a non-keyed service Type (IService in this example), then the non-keyed service is incorrectly injected instead of throwing an exception.

New behavior

An InvalidOperationException is now thrown when the FromKeyedServicesAttribute is used and the specified keyed service was not found; this is consistent with other cases when the requested service cannot be found due to lack of registration.

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 to target the new runtime, existing source code might require source changes to compile successfully.
  • Behavioral change: Existing binaries might behave differently at run time.

Reason for change

Adds missing validation logic to detect service misconfiguration bugs; this issue existed when the keyed service feature was added in v8.0.

Recommended action

If FromKeyedServicesAttribute is used, ensure that the corresponding service is registered as a keyed service, such as by using IServiceCollection.AddKeyedScoped(), IServiceCollection.AddKeyedSingleton() or IServiceCollection.AddKeyedTransient().

The fix will be backported to v8.0.9 so both v9.0 and v8.0 have the same behavior. If your application depends on the old behavior, a feature switch was added for v8.0.9 (but not v9.0) named "Microsoft.Extensions.DependencyInjection.AllowNonKeyedServiceInject" that if set to "true" will keep the old behavior.

Feature area

Containers, Core .NET libraries

Affected APIs

Microsoft.Extensions.DependencyInjection.FromKeyedServicesAttribute(object key) constructor


Associated WorkItem - 302333

Metadata

Metadata

Assignees

Labels

📌 seQUESTeredIdentifies that an issue has been imported into Quest.breaking-changeIndicates a .NET Core breaking changein-prThis issue will be closed (fixed) by an active pull request.

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions