ActivatorUtilities.CreateInstance が一貫して動作する
ActivatorUtilities.CreateInstance の動作が CreateFactory(Type, Type[]) とより一貫性のあるものになりました。 IServiceProviderIsService が依存関係挿入 (DI) コンテナーに存在しない場合、CreateInstance が CreateFactory(Type, Type[]) ロジックにフォールバックします。 そのロジックでは、指定されたすべての入力パラメーターとの一致が許可されるコンストラクターは 1 つだけです。
IServiceProviderIsService が存在するときの一般的なケースでは、CreateInstance
API で、すべての引数が有効な最長のコンストラクター オーバーロードが優先されます。 引数は、API への入力とすることも、コンテナーに登録することも、コンストラクター自体の既定値から使用することもできます。
2 つのコンストラクターを示す次のクラス定義について考えてみましょう。
public class A
{
A(B b, C c, string st = "default string") { }
A() { }
}
このクラス定義で、かつ IServiceProviderIsService
が存在するときは、B
、C
、string
を取る最初のコンストラクターを選択することで、ActivatorUtilities.CreateInstance<A>(serviceProvider, new C())
によって A
のインスタンスが作成されます。
導入されたバージョン
.NET 8 Preview 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[])
こちらもご覧ください
.NET