为什么使用Activator.CreateInstance创建的实例不解析引用?

时间:2013-07-19 09:57:48

标签: c# .net dependencies .net-assembly fusion

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

Application\Modules\XXX

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

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

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

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

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

知道为什么会发生这种情况以及如何解决这个问题?

感谢。

3 个答案:

答案 0 :(得分:3)

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

  

LoadFile不会将文件加载到LoadFrom上下文中,而则不会   使用加载路径解析依赖关系,如LoadFrom方法

您应该使用LoadFrom方法并从上下文加载,或者更好的是,如果可能,请使用Load并加载上下文。

答案 1 :(得分:2)

  

我正在使用Assembly.LoadFile(filename)

加载它们

这是一个非常常见的错误。它通常是因为只有LoadFile()有一篇不像gobbledegook读取的MSDN文章,加载上下文在.NET中是一个非常抽象的概念。

如果您故意希望找到相关的程序集,则只应使用LoadFile()。这是非常罕见的,只有像检查组件这样的程序才会这样做。像反汇编器这样的工具。

需要LoadFrom()才能让CLR在该目录中查找依赖程序集。一般要注意,这不是DLL Hell的保证修复,类型的标识包括它来自的程序集。具有相同命名空间名称和类型名称的类型存在于多个程序集中的问题。在单独目录中使用程序集组更可能出现的故障模式。特别是当您不控制其内容时,例如插件方案。 Mystifying InvalidCastExceptions可能是您的下一个克星,也是加载LoadFile()的程序集的一种非常常见的故障模式。程序员喜欢将文件组织到目录中,这是一种专业责任的OCD,与CLR喜欢避免DLL Hell的方式非常不兼容。如果这是插件方案的要求,那么请使用像MEF这样的插件框架来限制意外。

答案 2 :(得分: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