MEF: 「要求された型を 1 つ以上ロードできません。詳細については LoaderExceptions を取得してください」質問する

MEF: 「要求された型を 1 つ以上ロードできません。詳細については LoaderExceptions を取得してください」質問する

シナリオ: 別の dll で定義されたインターフェイス コントラクトに基づいて、実行時にプラグイン (エクスポート) をロードするために Managed Extensibility Framework を使用しています。Visual Studio ソリューションには、ホスト アプリケーション、クラス ライブラリ (インターフェイス「IPlugin」を定義)、インターフェイスを実装する別のクラス ライブラリ (エクスポート「MyPlugin.dll」) の 3 つの異なるプロジェクトがあります。

ホストは独自のルート ディレクトリでエクスポートを検索するため、テスト中はソリューション全体をビルドし、Plugin クラス ライブラリの bin/release フォルダーから Plugin.dll をホストのデバッグ ディレクトリにコピーして、ホストの DirectoryCatalog がそれを見つけて CompositionContainer に追加できるようにします。Plugin.dll は各リビルド後に自動的にコピーされないため、コントラクト/実装に変更を加えるたびに手動でコピーします。

ただし、最初に (更新された) Plugin.dll をコピーせずにホスト アプリケーションを実行したところ、構成中に例外がスローされました。

Unable to load one or more of the requested types. Retrieve the LoaderExceptions for more information

これはもちろん、インポートしようとしているPlugin.dllが実装しているという事実によるものです。異なるバージョンIPlugin の場合、プロパティ/メソッドのシグネチャが一致しません。制御および監視された環境では、プラグイン フォルダー内の古い IPlugin 実装を避けるだけで簡単にこれを回避することができますが、レガシー プラグインに遭遇する可能性のある運用環境では、このような想定に頼ることはできません。

問題は、この例外がComposeアクション全体を台無しにし、いいえエクスポートがインポートされます。一致しない IPlugin 実装は単に無視され、正しいバージョンの IPlugin を実装するカタログ内の他のエクスポートが引き続きインポートされるようにすることをお勧めします。

これを実現する方法はありますか? いくつかの選択肢が考えられます:

  • Composeを呼び出す前または呼び出すときに、CompositionContainer(「失敗したインポートを無視する」)に設定するフラグがあります。
  • <ImportMany()>属性に指定する同様のフラグがあります
  • Compose() の反復処理に「フック」して、各 (失敗した) インポートを個別に処理できる方法があります。
  • 強力な名前署名を使用して、何らかの方法で実装されたインポートのみを検索します現在IPluginのバージョン

アイデアは?

ベストアンサー1

私も遭遇したことがある同様の問題

そのような「悪い」アセンブリを無視したい場合、解決策は以下を呼び出すことです。アセンブリカタログ.パーツ.ToArray()各アセンブリ カタログの作成直後。これにより、ReflectionTypeLoadException言及したがトリガーされます。その後、例外をキャッチして、不良アセンブリを無視する機会が得られます。

すべての「適切な」アセンブリのオブジェクトを作成したらAssemblyCatalog、それらを に集約しAggregateCatalog、それをコンストラクターに渡すことができますCompositionContainer

おすすめ記事