2013-01-02 11 views
6

新しいAppDomainの特定の "extensions"ディレクトリからすべてのDLLを読み込んで、Reflection関連の情報を取得しています。別のAppDomainからアセンブリ参照を受け取る際の例外

これは私がしようとしているものです:私はこのDLLは、私の「拡張子」の内部に存在することを確認してください

public class AssemblyProxy : MarshalByRefObject 
{ 
    public Assembly LoadFile(string assemblyPath) 
    { 
     try 
     { 
     return Assembly.LoadFile(assemblyPath); 
     } 
     catch 
     { 
     return null; 
     } 
    } 
} 

を私はこのクラスを持っている私の溶液中での新しいライブラリAssemblyProxyを作成ディレクトリ。次に、次のコードを使用して、すべてのアセンブリを "extensions"ディレクトリから新しいAppDomainにロードします。

foreach(string extensionFile in Directory.GetFiles(ExtensionsDirectory, "*.dll")) 
{ 
     Type type = typeof(AssemblyProxy.AssemblyProxy); 
     var value = (AssemblyProxy.AssemblyProxy) Domain.CreateInstanceAndUnwrap(
      type.Assembly.FullName, 
      type.FullName); 

     var extensionAssembly = value.LoadFile(extensionFile); 

     types.AddRange(extensionAssembly.GetTypes()); 
} 

いくつかのDLLが正常にロードされますんが、いくつかのDLLに例外は次のようにスローされます。

Could not load file or assembly 'Drivers, Version=2.3.0.77, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.

EDITを:例外が新しいのAppDomainにスローされません。 DLLは新しいAppDomainに正常に読み込まれます。アセンブリ参照がメイン/呼び出しAppDomainに返されるとすぐに例外がスローされます。メイン/呼び出し元のAppDomainは参照を受信するだけでアセンブリをロードしようとしますか?

ありがとうございました。

あなたがメイン AppDomainが、それはアセンブリがディレクトリに配置されていないので、それらのアセンブリへのアクセスがある場合にのみ動作しますので、あなたは新しい AppDomainから Assemblyオブジェクトを返すべきではありません
+4

何を試しましたか? –

+0

['ReflectionLoadOnly'](http://msdn.microsoft.com/en-us/library/ms172331(v=vs.100).aspx)は、あなたの目的に十分ですか? –

+0

[CreateInstanceAndUnwrap](http://msdn.microsoft.com/en-us/library/system.appdomain.createinstancefromandunwrap.aspx)の何が問題ですか? – Algirdas

答えて

2

のAppDomainの相対検索パスに指定されたディレクトリにありません

一つleppieさんのコメントに従うために、これを回避する方法及び:

  1. あなたはAssemblyオブジェクトから必要な最低限の情報を含んでシリアル化されたタイプを作成します。
  2. 両方のAppDomainがアクセスできる新しいアセンブリにこの型を追加します。それをGACに追加することでこれを行う最も簡単な方法です。

もう1つの方法は、System.Reflectionの代わりにMono.Cecilを使用することです。 Mono.Cecilを使用すると、アセンブリを読み込まずに検査することができます。非常に簡単な例として、このanswerからの後半部分を見てください。

+0

'Assembly'オブジェクトに何か問題がありますか? 'ReflectionOnlyLoadFrom'を使用すると、同じ' Assembly'型のオブジェクト参照が正常に返されるためです。 – user1004959

+0

@ user1004959私はアセンブリオブジェクトを返すことはあなたがすべきことではないことを肯定します。おそらく、特定のアセンブリがメインのAppDomainにすべてロードされていた可能性があります。 foreachの最後の行にブレークポイントを追加し、プログラムを実行してから、Visual StudioのQuickWatch機能を使用して、System.AppDomain.CurrentDomain.GetAssemblies()を評価します。ロードされたアセンブリを見ることができれば、それはどうにか主AppDomainにロードされました。実験中にAssemblyResolveイベントを購読したことがありますか? –

関連する問題