2011-01-30 17 views
6

コンパイル時には参照されないが、実行時にはディレクトリカタログを介して検出される、さまざまなアセンブリから多数のクラスをインポートするクラスを含むアセンブリがあります。エクスポートするクラスは、インポートするアセンブリのホストアプリケーションで設定ファイルのカスタム構成セクションを定義します。ただし、インポートアセンブリのホストアプリケーションは、コンパイル時にエクスポートアセンブリを認識しないため、アセンブリにカスタムセクションハンドラの実装を使用するように読み込むことはできません。MEFエクスポートアセンブリのカスタム構成セクション

これを回避する方法の1つは、インポートアセンブリのホストアプリケーションアセンブリと同じフォルダにエクスポートアセンブリを配置することです。しかし、他の開発者がエクスポートアセンブリを保持するフォルダを構成できるようにしたいと考えています。

私ができることの1つは、起動時に開発者が設定したフォルダの内容をホストのフォルダにコピーすることです。しかし、私はむしろそうすることができるなら、余分に動く部品とコードを維持することをむしろ避けたい。これの周りに良い方法がありますか?カスタム設定セクションを定義するアセンブリを探すときにアプリケーションを追加ディレクトリに向ける方法はありますか?

+0

あなたの問題に対する答えを見つけ出すことができたなら、私は非常に似ている問題に直面しているので、それについて読んでみたいと思います。 –

答えて

6

StructureMapを使用してアセンブリを動的に検出する際に同じ問題が発生しました。 ConfigurationManagerは、Bin-FolderとGACでのみ、ConfigurationSectionの指定されたアセンブリを検索しているようです。アセンブリが現在のAppDomainに読み込まれても動作しないようです。

しかし、実際、のConfigurationSectionの議会はすでに簡単な回避策のために使用することができるロードされていること:

AppDomain.CurrentDomain.AssemblyResolve += (o, args) => 
     { 
      var loadedAssemblies = AppDomain.CurrentDomain.GetAssemblies(); 
      return loadedAssemblies.FirstOrDefault(asm => asm.FullName == args.Name); 
     }; 

に、AssemblyResolveイベントはCLRが特定のアセンブリを見つけることができない時はいつでも発射されます。 GetSection()の最初の呼び出しの前にコールバックを登録するようにしてください。

私のために働きます。

+1

優秀な解決策ヨアヒム、ありがとう!私はこれが働いているが、私は要求されたアセンブリ(args.Name)は、文字列内のバージョンとカルチャコンポーネントを持っていないが、ロードされたアセンブリ(asm.FullName)がしたという点で少し問題があった。そのため、文字列の一致は機能しませんでした。私が踏み込んだとき、他の要求されたアセンブリにはバージョンと文化がありましたが、何らかの理由で私が関心を持っていたのは何もありませんでした。そこで、検索をasm.FullName.Contains(args.Name)に変更しました。なぜバージョンと文化が1つのアセンブリの要求の一部ではないが、他のアセンブリのためのものなのか? –

+0

ありがとう、これは理にかなっています! P.S.余分な 'Where'を使う代わりに' loadedAssemblies.FirstOrDefault(a => a.FullName == args.Name); 'と書くだけでよいのです。 ; p –

+0

これが変更されました。ありがとうございました。 –

0

私が知る限り、設定セクションはGetSection()からアクセスされたときにのみ読み込まれます。あなたのモジュールコードがConfigurationManager.GetSection("myModuleConfigSection")を呼び出す唯一のものであれば、おそらく問題ではありません。この時点でアセンブリはAppDomainにロードされています。あなたのアセンブリがAppDomainにロードされる前にそのセクションが読み込まれている場合は、例外がスローされると思います。

AppDomainがアセンブリの解決に使用するプライベートビンのパスにモジュールパスを追加する可能性があります。追加のパスを追加すると、現在ロードされていないアセンブリを解決することができます。

+0

Matthew - ありがとう。セクションハンドラを持つモジュールは、MEFコンポジションをインスタンス化した後で呼び出しを行っているため、その時点でAppDomainにロードされていると想定しています(これはハンドラタイプを解決できなかったことに実際に驚いた理由です)。違いは、あなたが記述しているように私はConfigurationManager.GetSectionを呼び出さないということです。代わりに、ConfigurationManager.OpenExeConfigurationからConfigurationを取得してから、Configuration.GetSectionを呼び出しています。それが何らかの影響を与えるかどうかはわかりませんが、私はConfigurationManager.GetSectionのアプローチを試してみます。 –

関連する問題