0

我有一个奇怪的情况,即通过反射创建时使用了错误的程序集。

这是我的设置(简化):

项目1:类库

项目2:客户端应用程序

  • Project2 通过从特定路径 (C:\Project1) 反射创建 Project1.dll
  • Project2 还引用了 Project1.dll 以获得不同的功能。此引用复制 C:\Project2\bin\Debug 中的 Project1.dll。

相关反射代码为:
Assembly assembly = Assembly.LoadFrom(path);

问题:当我通过反射调用 Project1 时,即使我指定了 C:\Project1 路径,它实际上也使用了 bin\Debug 副本(不一定是正确的版本)。

问题:如何确保使用我提供的路径而不是首先找到的任何版本?

我理想的解决方案是将 Project1 一分为二,一个用于反射,一个用于参考,但在我的情况下这不是一个选项(它是,但它有额外的复杂性)。

谢谢你,
西蒙

4

1 回答 1

2

感谢您更新您的帖子。这一行显示了您遇到此行为的原因。

该方法LoadFrom按定义工作:

加载源上下文包含用户为其提供的路径未包含在通过探测搜索的目录中的程序集。LoadFrom、CreateInstanceFrom 和 ExecuteAssembly 是按路径加载的方法示例。

探测是在 GAC、主机程序集存储、正在执行的程序集的文件夹或正在执行的程序集的私有文件夹中查找程序集的过程。

由于您已经引用了程序集,它只返回与您在参数中提供的名称匹配的已加载程序集。

您正在寻找的方法是LoadFile. MSDN 声明如下:

使用 LoadFile 方法加载和检查具有相同标识但位于不同路径中的程序集。LoadFile 不会将文件加载到 LoadFrom 上下文中,也不会像 LoadFrom 方法那样使用加载路径解析依赖关系。


其他资源

Suzanne Cook 在她的博客 .NET CLR Notes 上写的LoadFile 与 LoadFrom 。

小心——这些不是一回事。

LoadFrom() 通过 Fusion,如果已经在 LoadFrom 上下文中加载了一个程序集,则可以将其重定向到不同路径但具有相同标识的另一个程序集。LoadFile() 根本不通过 Fusion 绑定 - 加载器只是继续并准确地加载*调用者请求的内容。它不使用 Load 或 LoadFrom 上下文。

所以, LoadFrom() 通常会给你你所要求的,但不一定。LoadFile() 适用于那些真正、真正想要确切要求的人。(*然而,从 v2 开始,策略将同时应用于 LoadFrom() 和 LoadFile(),因此 LoadFile() 不一定是请求的内容。此外,从 v2 开始,如果具有其标识的程序集位于GAC,将使用 GAC 副本。使用 ReflectionOnlyLoadFrom() 准确加载您想要的内容 - 但请注意,以这种方式加载的程序集无法执行。)

LoadFile() 有一个问题。由于它不使用绑定上下文,因此不会在其目录中自动找到其依赖项。如果它们在 Load 上下文中不可用,则必须订阅 AssemblyResolve 事件才能绑定到它们。

于 2014-07-14T21:41:50.573 回答