Description
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 with CreateFactory
, such that when IServiceProviderIsService
is not present in the DI container then CreateInstance
falls back to a CreateFactory
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, the CreateInstance
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:
public class A
{
A(B b, C c, string st = "default string") { }
A() { }
}
For the above class definition, with IServiceProviderIsService
, the expectation is for ActivatorUtilities.CreateInstance<A>(serviceProvider, new C())
to instantiate A
by picking the first constructor taking B
, C
and string
.
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 throws
if IServiceProviderIsService
is not present it falls back to CreateFactory
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
- Binary incompatible: Existing binaries may encounter a breaking change in behavior, such as failure to load/execute or different run-time behavior.
- Source incompatible: Source code may encounter a breaking change in behavior when targeting the new runtime/component/SDK, such as compile errors or different run-time behavior.
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