ActivatorUtilities.CreateInstance verhält sich konsistent
Das Verhalten von ActivatorUtilities.CreateInstance ist bei CreateFactory(Type, Type[]) jetzt konsistenter. Wenn IServiceProviderIsService im Container für die Abhängigkeitsinjektion (Dependency Injection, DI) nicht vorhanden ist, greift CreateInstance auf die CreateFactory(Type, Type[])-Logik zurück. In dieser Logik darf nur ein Konstruktor mit allen bereitgestellten Eingabeparametern übereinstimmen.
Im allgemeineren Fall, wenn IServiceProviderIsService vorhanden ist, bevorzugt die CreateInstance
-API die längste Konstruktorüberladung mit allen verfügbaren Argumenten. Die Argumente können in die API eingegeben, im Container registriert oder aus Standardwerten im Konstruktor selbst verfügbar sein.
Sehen Sie sich die folgende Klassendefinition mit zwei Konstruktoren an:
public class A
{
A(B b, C c, string st = "default string") { }
A() { }
}
Bei dieser Klassendefinition und wenn IServiceProviderIsService
vorhanden ist, wird A
von ActivatorUtilities.CreateInstance<A>(serviceProvider, new C())
durch Auswählen des ersten Konstruktors instanziiert, der B
, C
und string
akzeptiert.
Eingeführt in Version
.NET 8 Preview 1
Vorheriges Verhalten
ActivatorUtilities.CreateInstance verhielt sich in einigen Fällen unerwartet. Die Methode stellte sicher, dass alle erforderlichen Instanzen, die an sie übergeben wurden, im ausgewählten Konstruktor vorhanden waren. Die Konstruktorauswahl war jedoch fehlerhaft und unzuverlässig.
Neues Verhalten
CreateInstance versucht, den längsten Konstruktor zu finden, der allen Parametern basierend auf dem Verhalten von IServiceProviderIsService entspricht.
- Wenn keine Konstruktoren gefunden werden oder IServiceProviderIsService nicht vorhanden sind, greift die Methode auf CreateFactory(Type, Type[])-Logik zurück.
- Wenn mehrere Konstruktoren gefunden werden, wird eine InvalidOperationException ausgelöst.
Hinweis
Wenn IServiceProviderIsService falsch konfiguriert oder nicht vorhanden ist, funktioniert CreateInstance
möglicherweise falsch oder auf uneindeutige Weise.
Typ des Breaking Changes
Diese Änderung ist eine Verhaltensänderung.
Grund für die Änderung
Dieser Breaking Change wurde eingeführt, um einen Fehler zu beheben, bei dem sich das Verhalten je nach Reihenfolge der Definitionen der Konstruktorüberladungen geändert hat.
Empfohlene Maßnahme
Wenn Ihre App sich nach dem Upgrade auf .NET 8 anders verhält oder eine Ausnahme auslöst, überprüfen Sie sorgfältig die Konstruktordefinitionen für den betroffenen Instanztyp. Weitere Informationen finden Sie im Abschnitt Neues Verhalten.
Betroffene APIs
- Microsoft.Extensions.DependencyInjection.ActivatorUtilities.CreateInstance<T>(IServiceProvider, Object[])
- Microsoft.Extensions.DependencyInjection.ActivatorUtilities.CreateInstance(IServiceProvider, Type, Object[])