System.Runtime.Loader.AssemblyLoadContext クラス

この記事では、この API のリファレンス ドキュメントへの補足的な解説を提供します。

AssemblyLoadContext み込みコンテキストを表します。 概念的には、読み込みコンテキストによって、一連のアセンブリの読み込み、解決、およびアンロードのスコープが作成されます。

AssemblyLoadContext にアセンブリの読み込み分離を提供するために存在します。 これにより、同じアセンブリの複数のバージョンを 1 つのプロセス内に読み込むことができます。 これは、.NET Framework の複数 AppDomain のインスタンスによって提供される分離メカニズムを置き換えます。

Note

  • AssemblyLoadContext では、セキュリティ機能は提供されません。 すべてのコードには、プロセスの完全なアクセス許可があります。
  • .NET Core 2.0 - 2.2 でのみ、 AssemblyLoadContext 抽象クラスです。 これらのバージョンで具象クラスを作成するには、メソッドを実装します AssemblyLoadContext.Load(AssemblyName)

ランタイムでの使用方法

ランタイムは、次の 2 つのアセンブリ読み込みコンテキストを実装します。

  • AssemblyLoadContext.Defaultはランタイムの既定のコンテキストを表します。これは、アプリケーション メイン アセンブリとその静的依存関係に使用されます。
  • このメソッドは Assembly.LoadFile(String) 、最も基本的な AssemblyLoadContextアセンブリをインスタンス化して、読み込むアセンブリを分離します。 依存関係の解決なしで各アセンブリを独自 AssemblyLoadContext に読み込む単純な分離スキームがあります。

アプリケーションの使用状況

アプリケーションは独自 AssemblyLoadContext のソリューションを作成して、高度なシナリオ用のカスタム ソリューションを作成できます。 このカスタマイズでは、依存関係解決メカニズムの定義に重点を置いています。

マネージド AssemblyLoadContext アセンブリ解決を実装するための 2 つの拡張ポイントが用意されています。

  1. このメソッドは AssemblyLoadContext.Load(AssemblyName) 、アセンブリを解決、読み込み、および返す最初の機会 AssemblyLoadContext を提供します。 メソッドから制御が AssemblyLoadContext.Load(AssemblyName)nullった場合、ローダーはアセンブリ AssemblyLoadContext.Defaultを .
  2. アセンブリを AssemblyLoadContext.Default 解決できない場合、元 AssemblyLoadContext のユーザーはアセンブリを解決する 2 回目の機会を得ます。 ランタイムによってイベントが発生します Resolving

さらに、仮想メソッドを AssemblyLoadContext.LoadUnmanagedDll(String) 使用すると、既定のアンマネージド アセンブリ解決をカスタマイズできます。 既定の実装 nullでは、ランタイム検索で既定の検索ポリシーが使用されます。 ほとんどのシナリオでは、既定の検索ポリシーで十分です。

技術的な課題

  • 1 つのプロセスで複数のバージョンのランタイムを読み込むことはできません。

    注意

    複数のコピーまたは異なるバージョンのフレームワーク アセンブリを読み込むと、予期しない、診断が困難な動作につながる可能性があります。

    ヒント

    この分離の問題を解決するには、リモート処理またはプロセス間通信でプロセス境界を使用します。

  • アセンブリの読み込みのタイミングにより、テストとデバッグが困難になる可能性があります。 通常、アセンブリは、依存関係が直ちに解決されずに読み込まれます。 依存関係は、必要に応じて読み込まれます。

    • コードが依存アセンブリに分岐する場合。
    • コードがリソースを読み込む場合。
    • コードがアセンブリを明示的に読み込む場合。
  • 実装では、異なるバージョンを AssemblyLoadContext.Load(AssemblyName) 存在させるために分離する必要がある可能性がある新しい依存関係を追加できます。 最も自然な実装では、これらの依存関係が既定のコンテキストに配置されます。 慎重な設計により、新しい依存関係を分離できます。

  • 同じアセンブリが異なるコンテキストに複数回読み込まれます。

    • これにより、"'Sample.Plugin' 型のオブジェクトを 'Sample.Plugin' 型にキャストできません" などのエラー メッセージが混乱する可能性があります。
    • 分離境界を越えたマーシャリングは簡単ではありません。 一般的な解決策は、既定の読み込みコンテキストにのみ読み込まれるアセンブリで定義されたインターフェイスを使用することです。