从另一个AppDomain接收程序集引用时的异常

use*_*959 6 .net c# dll appdomain

我正在从新的AppDomain中的特定"扩展"目录加载所有DLL,以从中获取一些与Reflection相关的信息.

这就是我正在尝试的:

我AssemblyProxy在我的解决方案中创建了一个新库,它只有这个类:

public class AssemblyProxy : MarshalByRefObject
{
    public Assembly LoadFile( string assemblyPath )
    {
      try
      {
        return Assembly.LoadFile( assemblyPath );
      }
      catch
      {
        return null;
      }
    }
}
Run Code Online (Sandbox Code Playgroud)

我确保这个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() );
}
Run Code Online (Sandbox Code Playgroud)

一些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是否仅在接收引用时尝试自行加载程序集?

谢谢.

Pan*_*nis 3

您不应该Assembly从 new 返回对象AppDomain,因为只有当您的 main 能够访问那些它无法访问的程序集时,这才有效AppDomain,因为程序集位于以下目录中:

避免这种情况的一种方法是遵循 leppie 的评论:

  1. 创建一个序列化类型,其中包含对象所需的最少信息Assembly。
  2. 将此类型添加到两个 AppDomain 都可以访问的新程序集中。最简单的方法是将其添加到 GAC 中。

另一种方法是使用Mono.Cecil而不是System.Reflection. Mono.Cecil 将允许您在不加载程序集的情况下检查它们。对于一个非常简单的示例,请查看此答案的后半部分。