АктивацияUtilities.CreateInstance работает согласованно
Поведение ActivatorUtilities.CreateInstance теперь более согласовано с CreateFactory(Type, Type[]). Если IServiceProviderIsService в контейнере внедрения зависимостей (DI) отсутствует, CreateInstance вернитесь к логике CreateFactory(Type, Type[]) . В этой логике только один конструктор может соответствовать всем предоставленным входным параметрам.
В более общем случае, когда IServiceProviderIsService присутствует, CreateInstance
API предпочитает самую длинную перегрузку конструктора, которая имеет все доступные аргументы. Аргументы могут быть входными данными в API, зарегистрированными в контейнере или доступными из значений по умолчанию в самом конструкторе.
Рассмотрим следующее определение класса, показывающее два конструктора:
public class A
{
A(B b, C c, string st = "default string") { }
A() { }
}
Для определения этого класса и при IServiceProviderIsService
наличии создается экземплярA
, ActivatorUtilities.CreateInstance<A>(serviceProvider, new C())
выбрав первый конструктор, который принимает B
, C
и string
.
Представленные версии
.NET 8( предварительная версия 1)
Прежнее поведение
ActivatorUtilities.CreateInstance в некоторых случаях непредвиденное поведение. Он убедитесь, что все необходимые экземпляры, переданные в него, существуют в выбранном конструкторе. Однако выбор конструктора был ошибкой и ненадежным.
Новое поведение
CreateInstance пытается найти самый длинный конструктор, соответствующий всем параметрам на основе поведения IServiceProviderIsService.
- Если конструкторы не найдены или IServiceProviderIsService отсутствуют, он возвращается к CreateFactory(Type, Type[]) логике.
- Если он находит несколько конструкторов, он создает InvalidOperationExceptionисключение.
Примечание.
Если IServiceProviderIsService настроен неправильно или не существует, CreateInstance
может работать неправильно или неоднозначно.
Тип критического изменения
Причина изменения
Это изменение было введено для исправления ошибки, в которой поведение изменилось в зависимости от порядка определений перегрузки конструктора.
Рекомендуемое действие
Если приложение начинает вести себя по-разному или вызывает исключение после обновления до .NET 8, тщательно изучите определения конструктора для затронутого типа экземпляра. Ознакомьтесь с разделом "Новое поведение ".
Затронутые API
- Microsoft.Extensions.DependencyInjection.ActivatorUtilities.CreateInstance<T>(IServiceProvider, Object[])
- Microsoft.Extensions.DependencyInjection.ActivatorUtilities.CreateInstance(IServiceProvider, Type, Object[])