ActivatorUtilities.CreateInstance se comporta de forma coherente.
El comportamiento de ActivatorUtilities.CreateInstance ahora es más coherente con CreateFactory(Type, Type[]). Cuando IServiceProviderIsService no está presente en el contenedor de inserción de dependencias (DI), CreateInstance recurre a la lógica CreateFactory(Type, Type[]). En esa lógica, solo se permite que un constructor coincida con todos los parámetros de entrada proporcionados.
En el caso más general cuando IServiceProviderIsService está presente, la API CreateInstance
prefiere la sobrecarga de constructor más larga que tiene todos sus argumentos disponibles. Los argumentos pueden ser insertados en la API, registrados en el contenedor o disponibles a partir de valores predeterminados en el propio constructor.
Considere la siguiente definición de clase que muestra dos constructores:
public class A
{
A(B b, C c, string st = "default string") { }
A() { }
}
Para esta definición de clase y, cuando IServiceProviderIsService
está presente, ActivatorUtilities.CreateInstance<A>(serviceProvider, new C())
crea instancias de A
seleccionando el primer constructor que toma B
, C
y string
.
Versión introducida
.NET 8 Preview 1
Comportamiento anterior
ActivatorUtilities.CreateInstance se comportó inesperadamente en algunos casos. Se ha asegurado de que todas las instancias necesarias que se le han pasado existían en el constructor elegido. Sin embargo, la selección del constructor daba errores y era poco fiable.
Comportamiento nuevo
CreateInstance intenta encontrar el constructor más largo que coincida con todos los parámetros en función del comportamiento de IServiceProviderIsService.
- Si no se encuentra ningún constructor o si IServiceProviderIsService no está presente, recurre a la lógica CreateFactory(Type, Type[]).
- Si encuentra más de un constructor, produce InvalidOperationException.
Nota
Si IServiceProviderIsService está configurado incorrectamente o no existe, CreateInstance
puede funcionar incorrectamente o ambiguamente.
Tipo de cambio importante
Este es un cambio de comportamiento.
Motivo del cambio
Este cambio se introdujo para corregir un error en el que el comportamiento cambió en función del orden de las definiciones de sobrecarga del constructor.
Acción recomendada
Si la aplicación comienza a comportarse de forma diferente o inicia una excepción después de actualizar a .NET 8, examine detenidamente las definiciones de constructor para el tipo de instancia afectado. Consulte la sección Nuevo comportamiento.
API afectadas
- Microsoft.Extensions.DependencyInjection.ActivatorUtilities.CreateInstance<T>(IServiceProvider, Object[])
- Microsoft.Extensions.DependencyInjection.ActivatorUtilities.CreateInstance(IServiceProvider, Type, Object[])