ActivatorUtilities.CreateInstance se comporta de forma consistente
O comportamento de ActivatorUtilities.CreateInstance agora é mais consistente com CreateFactory(Type, Type[]). Quando IServiceProviderIsService não está presente no contêiner de DI (injeção de dependência), CreateInstance reverte para a lógica CreateFactory(Type, Type[]). Nessa lógica, apenas um construtor tem permissão para fazer a correspondência com todos os parâmetros de entrada fornecidos.
No caso mais geral, quando IServiceProviderIsService está presente, a API CreateInstance
prefere a sobrecarga de construtor mais longa que tem todos os argumentos disponíveis. Os argumentos podem ser inseridos na API, registrados no contêiner ou estar disponíveis 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())
cria uma instância de A
escolhendo o primeiro construtor que usa B
, C
e string
.
Versão introduzida
.NET 8 versão prévia 1
Comportamento anterior
ActivatorUtilities.CreateInstance se comportou de forma inesperada em alguns casos. Ele verificou se todas as instâncias necessárias passadas para ele existiam no construtor escolhido. No entanto, a seleção do construtor tinha um bug e não era confiável.
Novo comportamento
CreateInstance tenta encontrar o construtor mais longo que corresponda a todos os parâmetros com base no comportamento de IServiceProviderIsService.
- Se nenhum construtor for encontrado ou se IServiceProviderIsService não estiver presente, ele reverterá para a lógica CreateFactory(Type, Type[]).
- Caso encontre mais de um construtor, ele gerará um InvalidOperationException.
Observação
Se IServiceProviderIsService estiver configurado incorretamente ou não existir, CreateInstance
poderá funcionar de forma incorreta ou ambígua.
Tipo de alteração interruptiva
Esta é uma alteração comportamental.
Motivo da alteração
Essa alteração foi introduzida para corrigir um bug em que o comportamento mudava de acordo com a ordem das definições de sobrecarga do construtor.
Ação recomendada
Se o aplicativo começar a se comportar de forma diferente ou gerar 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. Confira a seção Novo comportamento.
APIs afetadas
- Microsoft.Extensions.DependencyInjection.ActivatorUtilities.CreateInstance<T>(IServiceProvider, Object[])
- Microsoft.Extensions.DependencyInjection.ActivatorUtilities.CreateInstance(IServiceProvider, Type, Object[])