AktywatorUtilities.CreateInstance zachowuje się spójnie
Zachowanie funkcji ActivatorUtilities.CreateInstance jest teraz bardziej spójne z elementem CreateFactory(Type, Type[]). Gdy IServiceProviderIsService nie występuje w kontenerze wstrzykiwania zależności (DI), CreateInstance wraca do CreateFactory(Type, Type[]) logiki. W tej logice tylko jeden konstruktor może być zgodny ze wszystkimi podanymi parametrami wejściowymi.
W bardziej ogólnym przypadku, gdy IServiceProviderIsService jest obecny, CreateInstance
interfejs API preferuje najdłuższe przeciążenie konstruktora, które ma wszystkie dostępne argumenty. Argumenty mogą być danymi wejściowymi interfejsu API, zarejestrowanymi w kontenerze lub dostępnymi z wartości domyślnych w samym konstruktorze.
Rozważmy następującą definicję klasy przedstawiającą dwa konstruktory:
public class A
{
A(B b, C c, string st = "default string") { }
A() { }
}
W przypadku tej definicji klasy, a gdy IServiceProviderIsService
jest obecna, tworzy wystąpienie A
przez wybranie pierwszego konstruktora, ActivatorUtilities.CreateInstance<A>(serviceProvider, new C())
który przyjmuje B
, C
i string
.
Wprowadzona wersja
.NET 8 (wersja zapoznawcza 1)
Poprzednie zachowanie
ActivatorUtilities.CreateInstance zachowywał się nieoczekiwanie w niektórych przypadkach. Upewniono się, że wszystkie wymagane wystąpienia przekazane do niego istniały w wybranym konstruktorze. Jednak wybór konstruktora był usterka i zawodny.
Nowe zachowanie
CreateInstance próbuje znaleźć najdłuższy konstruktor, który pasuje do wszystkich parametrów w oparciu o zachowanie klasy IServiceProviderIsService.
- Jeśli nie znaleziono żadnych konstruktorów lub jeśli IServiceProviderIsService nie ma ich, wraca do CreateFactory(Type, Type[]) logiki.
- Jeśli znajdzie więcej niż jeden konstruktor, zgłasza błąd InvalidOperationException.
Uwaga
Jeśli IServiceProviderIsService skonfigurowano niepoprawnie lub nie istnieje, CreateInstance
może działać niepoprawnie lub niejednoznacznie.
Typ zmiany powodującej niezgodność
Ta zmiana jest zmianą behawioralną.
Przyczyna wprowadzenia zmiany
Ta zmiana została wprowadzona w celu naprawienia usterki, w której zachowanie zmieniło się w zależności od kolejności definicji przeciążenia konstruktora.
Zalecana akcja
Jeśli aplikacja działa inaczej lub zgłasza wyjątek po uaktualnieniu do platformy .NET 8, dokładnie zbadaj definicje konstruktorów dla danego typu wystąpienia. Zapoznaj się z sekcją Nowe zachowanie .
Dotyczy interfejsów API
- Microsoft.Extensions.DependencyInjection.ActivatorUtilities.CreateInstance<T>(IServiceProvider, Object[])
- Microsoft.Extensions.DependencyInjection.ActivatorUtilities.CreateInstance(IServiceProvider, Type, Object[])