[Breaking change]: ActivatorUtilities.CreateInstance is creating non-empty generic collections #39216
Open
1 of 3 tasks
Labels
breaking-change
Indicates a .NET Core breaking change
🏁 Release: .NET 8
Work items for the .NET 8 release
Description
Generic collections that have copy constructors are initialized with elements, when using
ActivatorUtilities.CreateInstance
/ActivatorUtilities.GetServiceOrCreateInstance
.Example:
Version
.NET 8 GA
Previous behavior
The
collection
object is an empty instance ofObservableCollection
.ActivatorUtilities.CreateInstance
used the constructorpublic ObservableCollection();
New behavior
The
collection
object is an instance ofObservableCollection
with two elements (an instance ofTest
and another ofTest2
).ActivatorUtilities.CreateInstance
is now choosing the constructorpublic ObservableCollection(IEnumerable<T> collection);
Type of breaking change
Reason for change
It should be related with:
ActivatorUtilities.CreateInstance
behaves consistently independent of ctor definition order #31785Currently,
ActivatorUtilities.CreateInstance
is choosing the constructor with most parameters that can be resolved fromIServiceProviderIsService
(since I'm not given any parameter to be used on the constructor), while previously it would pick the constructor with most parameters that could be resolved from the given ones (choosing the parameteless constructor, in this example).Recommended action
I'm not sure on the workaround.
This issue is affecting a custom JSON deserializer that uses
ActivatorUtilities.GetServiceOrCreateInstance
to instantiate the needed types (some of them are .Net generic collections). I can't change the types being sent on the JSON and I know that collections must be empty after initalization (and then filled up with the elements from the JSON payload), I maybe register custom collections on the dependency injection container to replace the .Net ones (inheritance + construtor overload). Other workarounds are very welcome.Maybe it would make sense to make sure that
ActivatorUtilities.GetServiceOrCreateInstance
chooses the parameterless constructor on those cases - generic collections with copy constructors (by moving the parameteless construtor afterwards the on requestingIEnumerable<T>
and by adding theActivatorUtilitiesConstructorAttribute
to it).Feature area
C#, Core .NET libraries, Extensions
Affected APIs
ActivatorUtilities.CreateInstance
ActivatorUtilities.GetServiceOrCreateInstance
Associated WorkItem - 206386
The text was updated successfully, but these errors were encountered: