ActivatorUtilities.CreateInstance se comporta consistentemente
O comportamento de ActivatorUtilities.CreateInstance é agora mais consistente com CreateFactory(Type, Type[]). Quando IServiceProviderIsService não está presente no recipiente CreateInstance de injeção de dependência (DI), recorre à CreateFactory(Type, Type[]) lógica. Nessa lógica, apenas um construtor tem permissão para corresponder com todos os parâmetros de entrada fornecidos.
No caso mais geral quando IServiceProviderIsService está presente, a CreateInstance
API prefere a sobrecarga de construtor mais longa que tem todos os seus argumentos disponíveis. Os argumentos podem ser inseridos na API, registrados no contêiner ou disponíveis a partir de valores padrão no próprio construtor.
Considere a seguinte definição de classe mostrando dois construtores:
public class A
{
A(B b, C c, string st = "default string") { }
A() { }
}
Para essa definição de classe, e quando IServiceProviderIsService
está presente, ActivatorUtilities.CreateInstance<A>(serviceProvider, new C())
instancia A
escolhendo o primeiro construtor que leva B
, C
e string
.
Versão introduzida
.NET 8 Visualização 1
Comportamento anterior
ActivatorUtilities.CreateInstance comportou-se inesperadamente em alguns casos. Ele se certificou de que todas as instâncias necessárias passadas para ele existiam no construtor escolhido. No entanto, a seleção do construtor foi buggy e não confiável.
Novo comportamento
CreateInstance tenta encontrar o construtor mais longo que corresponde a todos os parâmetros com base no comportamento do IServiceProviderIsService.
- Se nenhum construtor for encontrado ou se IServiceProviderIsService não estiver presente, ele volta à CreateFactory(Type, Type[]) lógica.
- Se ele encontrar mais de um construtor, ele lança um InvalidOperationException.
Nota
Se IServiceProviderIsService estiver configurado incorretamente ou não existir, CreateInstance
pode funcionar incorretamente ou de forma ambígua.
Tipo de mudança de rutura
Esta mudança é uma mudança comportamental.
Razão para a alteração
Essa alteração foi introduzida para corrigir um bug em que o comportamento mudava dependendo da ordem das definições de sobrecarga do construtor.
Ação recomendada
Se seu aplicativo começar a se comportar de forma diferente ou lançar uma exceção após a atualização para o .NET 8, examine cuidadosamente as definições do construtor para o tipo de instância afetado. Consulte a seção Novo comportamento .
APIs afetadas
- Microsoft.Extensions.DependencyInjection.ActivatorUtilities.CreateInstance<T>(IServiceProvider, Object[])
- Microsoft.Extensions.DependencyInjection.ActivatorUtilities.CreateInstance(IServiceProvider, Type, Object[])