7

新しい AppDomain の特定の「拡張機能」ディレクトリからすべての DLL をロードして、そこからリフレクション関連の情報を取得しています。

これは私がしようとしているものです:

AssemblyProxyこのクラスだけを持つソリューションに新しいライブラリを作成しました。

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

この DLL が "extensions" ディレクトリ内にあることを確認します。次に、次のコードを使用して、すべてのアセンブリを「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.

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

ありがとう。

4

1 に答える 1

3

Assemblynew からオブジェクトを返す必要はありません。これは、アセンブリが次のディレクトリにあるため、アクセスできないアセンブリにアクセスできるAppDomain場合にのみ機能するためです。AppDomain

これを回避する 1 つの方法は、leppie のコメントに従います。

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

別のアプローチは、の代わりにMono.CecilSystem.Reflectionを使用することです。Mono.Cecil を使用すると、アセンブリをロードせずに検査できます。非常に単純な例については、この回答の後半を見てください。

于 2013-01-04T10:47:16.330 に答える