【问题标题】:How to add assemblies reference to a loaded assembly?如何将程序集引用添加到加载的程序集?
【发布时间】:2017-05-08 16:59:20
【问题描述】:

我正在使用 .NET 反射来检查程序集的内容。不幸的是,在检查我的程序集引用但在其他地方定义的类型时,这并不是那么简单。

所以,假设我有两个Assembly

Assembly assembly1 = Assembly.LoadFrom("MyAssembly.dll");
Assembly assembly2 = Assembly.LoadFrom("MyReferencedAssembly.dll");

assembly1 中有在assembly2 中定义的类型,所以我想要的基本上是将assembly2 加载到assembly1 中。

如何以编程方式实现这一点?

尝试使用AppDomain.Load

按照 cmets 的建议,我正在尝试这个:

private Assembly GetAssembly()
{
  string[] referencedAssemblyPaths = new[] { "MyReferencedAssembly.dll" };

  var domaininfo = new AppDomainSetup();
  domaininfo.ApplicationBase = Environment.CurrentDirectory;
  Evidence adevidence = AppDomain.CurrentDomain.Evidence;
  var domain = AppDomain.CreateDomain("AssemblyContextDomain", adevidence, domaininfo);

  Assembly assembly = domain.Load(LoadFile("MyAssembly.dll"));

  foreach (var path in referencedAssemblyPaths)
  {
    domain.Load(LoadFile(path));
  }

  return assembly;
}

private static byte[] LoadFile(string filename)
{
  FileStream fs = new FileStream(filename, FileMode.Open);
  byte[] buffer = new byte[(int)fs.Length];
  fs.Read(buffer, 0, buffer.Length);
  fs.Close();

  return buffer;
}

但是当我得到FileNotFoundException 时调用domain.Load(LoadFile("MyAssembly.dll")) 时出现问题:

无法加载文件或程序集“MyAssembly,Version=10.0.0.0,Culture=neutral,PublicKeyToken=null”或其依赖项之一。系统找不到指定的文件。

调试信息 通过调试我可以看到文件存在于正确的位置,LoadFile 成功返回了流。问题出在AppDomain.Load 中,它引发了该异常。

  • 为什么报告找不到文件?
  • 它是否试图加载 deendencies,而那些是它找不到的文件?但是我会在之后立即加载依赖项...

我到底应该如何加载程序集及其依赖项?

【问题讨论】:

  • 如果我对您的理解正确,那么您可以使用AppDomain.AssemblyResolve。详情请看这里:stackoverflow.com/questions/24956949/…stackoverflow.com/questions/59220/…
  • @elgonzo:感谢您的建议。第二个问题似乎很有希望,但我想获得一些代码,因为我可以在 Internet 上看到很多。会推荐什么方法?该问题基本上缺少一些代码示例,如果您发布答案会很酷
  • 查看 MSDN 文档(我的第一条评论中的链接)作为示例。 MSDN 还有更多关于 AssemblyResolve 事件的文档,例如:msdn.microsoft.com/en-us/library/ff527268(v=vs.110).aspx。否则,谷歌就不远了。抱歉,不想用代码示例写答案,因为我附近没有 VS,而且我担心我无法从头顶编写关于程序集加载的正确代码:(
  • 唯一没有在程序集中定义的类型是该类型用作变量或参数。那么,.net 是做什么的呢? - 它首先遍历 DLL,GAC,然后是 bin,然后是本地文件夹。所以,你必须做同样的事情。另见stackoverflow.com/questions/23247521/…
  • 大家好。我已经用更多细节和我尝试过的一些代码更新了这个问题。

标签: c# .net reflection .net-assembly


【解决方案1】:

加载程序集时,.Net 会自动尝试加载所有依赖项。 FileNotFoundException 可能是指“其依赖项之一”而不是实际的程序集文件 - 您可以使用融合日志记录 (How to enable assembly bind failure logging (Fusion) in .NET) 来确定确切的失败原因。正如 cmets 中所建议的,您可以使用 AppDomain.AssemblyResolve 为查找引用的程序集提供额外的逻辑,但是您需要将事件实际附加到您的域中,我在您的代码中没有看到 - 所以 domain.AssemblyResolve += ...。这通常仅在引用的程序集位于不同的文件夹中或默认搜索模式未找到时才需要,因此如果您所追求的只是调试它无法加载的原因,那么融合日志就是关键。

AppDomains 可能有点棘手,这就是它们在 .Net Core (https://blogs.msdn.microsoft.com/dotnet/2016/02/10/porting-to-net-core/) 中被替换/未实现的原因。

如果您只想加载程序集以首先检查它,而不加载所有依赖项,则可以仅加载它以进行反射 - https://msdn.microsoft.com/en-us/library/0et80c7k.aspx,这将不允许您执行程序集中的任何代码,所以你需要在稍后的某个时间点做实际的负载。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多