[Breaking change]: ActivatorUtilities.CreateInstance
behaves consistently independent of ctor definition order
#31785
Labels
breaking-change
Indicates a .NET Core breaking change
🏁 Release: .NET 8
Work items for the .NET 8 release
doc-idea
Indicates issues that are suggestions for new topics [org][type][category]
Pri1
High priority, do before Pri2 and Pri3
📌 seQUESTered
Identifies that an issue has been imported into Quest.
source incompatible
Source code may encounter a breaking change in behavior when targeting the new version.
Description
We introduced a breaking change in order to fix the bug with behavior dependence on order of constructor definition.
As part of this fix we also made the behavior of
CreateInstance
more coherent withCreateFactory
, such that whenIServiceProviderIsService
is not present in the DI container thenCreateInstance
falls back to aCreateFactory
logic, where only one constructor is allowed to match with all the required given input parameters.In a more general case when we expect
IServiceProviderIsService
to be present, theCreateInstance
API prefers the longest constructor overload that has all its arguments either available as input to the API or as registered in the container or available with default values to the constructor itself.Example:
For the above class definition, with
IServiceProviderIsService
, the expectation is forActivatorUtilities.CreateInstance<A>(serviceProvider, new C())
to instantiateA
by picking the first constructor takingB
,C
andstring
.Version
.NET 8 Preview 1
Previous behavior
ActivatorUtilities.CreateInstance
had cases where it behaved unexpectedly.The API would make sure all required instances passed to it exist in the constructor being picked. But the constructor selection was buggy and not reliable.
New behavior
General idea:
CreateInstance
tries to find the longest constructor matching all parameters based on the behavior of IServiceProviderIsService.If none are found, try to fallback to
CreateFactory
, if it finds more than one constructor it throwsif
IServiceProviderIsService
is not present it falls back toCreateFactory
logic.If
IServiceProviderIsService
is configured wrong, or does not exist, it is OK for the API to function incorrectly or ambiguously.Type of breaking change
Reason for change
To fix the bug with inconsistent behavior when constructor overload definition order changes
Recommended action
Carefully examine constructor definitions if for the given instance type if you are suddenly getting failure now after updating to .NET 8 Preview 1. (Refer to new behavior above).
Feature area
C#, Core .NET libraries, Extensions
Affected APIs
ActivatorUtilities.CreateInstance
Fixed in PR dotnet/runtime#75846
Associated WorkItem - 60828
The text was updated successfully, but these errors were encountered: