c# - 如何将程序集引用添加到加载的程序集?

标签 c# .net reflection .net-assembly

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

所以,假设我有两个 Assembly:

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

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

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

尝试使用 AppDomain.Load

正如评论中所建议的,我正在尝试这样做:

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;
}

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

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

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

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

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

最佳答案

加载程序集时,.Net 会自动尝试加载所有依赖项。 FileNotFoundException 可能指的是“其依赖项之一”而不是实际的程序集文件 - 您可以使用融合日志记录 (How to enable assembly bind failure logging (Fusion) in .NET) 来确定确切的失败原因。正如评论中所建议的,您可以使用 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 ,这将不允许您执行程序集中的任何代码,因此您需要在稍后的某个时间点执行实际加载。

关于c# - 如何将程序集引用添加到加载的程序集?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43836972/

相关文章:

c# - 使用反射区分重载方法的泛型和非泛型版本

c# - 对 ViewModel 属性进行修饰以使用不同的名称进行绑定(bind)

c# - 在 telerik winforms 下显示 cellvalidation 错误消息

c# - 是否可以使用 Visual Studio 从 Android Firebase 接收数据并向 mysql 发送数据

c# - 静态类的克隆

c# - 我使用反射的自定义映射可以更快吗?

c# - Fluent NHibernate 双向多对一 IConvertible 异常

c# - 线程 : Thread. CurrentThread.Name 和 Thread.CurrentThread.ManagedThereadId

c# - 如何通过 Entity Framework 搜索对象及其子项?

C# Xml 到 Linq 删除一个项目