1

我有一个具有以下文件夹结构的应用程序:

Application\Modules\XXX

当然,XXX 中的任何程序集都会在 XXX 中找到其他程序集。

一些实例化使用反射的实例会出现问题:

TProvider providerInstance = (TProvider)Activator.CreateInstance(providerType));

TProvider 有一个方法,该方法返回在另一个程序集中定义的类(也存储在 XXX 中)。当调用必须加载引用的 providerInstance 的该方法时,即使依赖项位于同一 XXX 文件夹中,我也会收到有关找不到依赖程序集的 FileNotFoundException 异常。

查看融合日志,程序集加载器仅检查 Application 文件夹,而不是 XXX ...

关于为什么会发生这种情况以及如何解决它的任何想法?

谢谢。

4

3 回答 3

3

原因是您正在使用LoadFile方法加载程序集:

LoadFile 不会将文件加载到 LoadFrom 上下文中,也不会像 LoadFrom 方法那样使用加载路径解析依赖关系

您应该使用LoadFrom方法和从上下文加载,或者,如果可能的话,最好使用Load和加载上下文。

于 2013-07-19T10:32:14.990 回答
2

我正在使用 Assembly.LoadFile(filename) 加载它们

这是一个很常见的错误。之所以经常这样做,是因为只有 LoadFile() 有一篇不错的 MSDN 文章,读起来不像 gobbledegook,加载上下文在 .NET 中是一个非常抽象的概念。

只有在您故意不希望找到依赖程序集时才应使用 LoadFile() 。这是非常罕见的,只有执行检查程序集之类的程序才会这样做。反汇编器之类的工具。

需要 LoadFrom() 才能让 CLR 在该目录中查找相关程序集。通常请注意,这不是 DLL Hell 的保证修复,类型的标识包括它来自的程序集。具有相同命名空间名称的类型出现问题,并且类型名称存在于多个程序集中。一种故障模式,在单独目录中的程序集组中更有可能发生故障。尤其是当您不控制其内容时,例如插件场景。神秘的 InvalidCastExceptions 可能是您的下一个克星,对于使用 LoadFile() 加载的程序集来说,这也是一种非常常见的故障模式。程序员喜欢将文件组织到目录中,这有点强迫症,这是一种职业责任,并且与 CLR 喜欢避免 DLL Hell 的方式完全不兼容。

于 2013-07-19T11:11:13.840 回答
0

要指示 CLR 在 Modules\XXX 子目录下进行探测,请applicationname.exe.config使用任何文本编辑器或使用提供的 App.config 文件创建一个新的配置文件,并将该文件保存在包含 applicationname.exe应用程序的文件夹中,在本示例中为 Application .

<configuration>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <probing privatePath="Modules\XXX"/>
    </assemblyBinding>
  </runtime>
</configuration>

假设您想使用绝对路径或相对路径指定程序集(与 .exe 不在同一目录层次结构中),请<codebase>改用,无论如何这两种方法都与 xml 配置文件的使用有关。

Assembly.LoadFrom(...)

确实是<codebase>等价的;可以采用相对路径和绝对路径

主要参考:Pro C# 5.0 和 .net 4.5

于 2013-07-19T10:47:32.437 回答