ActivatorUtilities.CreateInstance 的行为现在与 CreateFactory(Type, Type[]) 更加一致。 当依赖项注入 (DI) 容器中没有 IServiceProviderIsService 时,CreateInstance 将回退到 CreateFactory(Type, Type[]) 逻辑。 在该逻辑中,只允许一个构造函数与提供的所有输入参数匹配。
在存在 IServiceProviderIsService 的较一般情况下,CreateInstance API 优先选择所有参数均可用的最长构造函数重载。 参数可以是 API 的输入、在容器中注册的,也可以从构造函数本身的默认值获取。
请考虑以下类定义,其中显示了两个构造函数:
public class A
{
A(B b, C c, string st = "default string") { }
A() { }
}
对于此类定义,如果IServiceProviderIsService存在,ActivatorUtilities.CreateInstance<A>(serviceProvider, new C())则通过选取采用A的第一个构造函数来实例化B,C以及string。
已引入的版本
.NET 8 预览版 1
以前的行为
ActivatorUtilities.CreateInstance 在某些情形下,行为表现不如预期。 它确保传递给它的所有必需实例都存在于所选构造函数中。 但是,构造函数选择出现了 bug 且不可靠。
新行为
CreateInstance 尝试根据行为 IServiceProviderIsService查找与所有参数匹配的最长构造函数。
- 如果未找到构造函数或 IServiceProviderIsService 不存在构造函数,则它会回退到 CreateFactory(Type, Type[]) 逻辑。
- 如果找到多个构造函数,则会抛出一个 InvalidOperationException。
注释
如果 IServiceProviderIsService 配置不正确或不存在, CreateInstance 则可能无法正常运行或含糊不清。
破坏性变更的类型
此更改为行为更改。
更改原因
引入此更改是为了修复一个 bug,其中行为根据构造函数重载定义的顺序而更改。
建议的措施
如果应用在升级到 .NET 8 后开始发生不同行为或引发异常,请仔细检查受影响的实例类型的构造函数定义。 请参阅 “新建行为 ”部分。
受影响的 API
- Microsoft.Extensions.DependencyInjection.ActivatorUtilities.CreateInstance<T>(IServiceProvider, Object[])
- Microsoft.Extensions.DependencyInjection.ActivatorUtilities.CreateInstance(IServiceProvider, Type, Object[])