【问题标题】:Dynamically loading assembly: why this code works?动态加载程序集:为什么这段代码有效?
【发布时间】:2011-11-19 20:06:47
【问题描述】:

在我的情况下,有三个组件:Consumer 类、IExposedIface 接口和实现IExposedIfaceExposed 类。 ConsumerExposed 都与 IExposedIface 静态链接,但 Consumer 没有对 Exposed 的编译时引用。

我正在尝试提出一个方案,该方案允许Consumer 在运行时加载不同版本的Exposed(取决于输入数据 - 假设每个输入文档都包含有关 Exposed 应该是哪个版本的信息用来处理它)。为了实现这一点,我开始研究 AppDomains,现在我有了一个可以运行的基本版本。

到目前为止,在我看来,将IExposedIface 程序集提供给Exposed 程序集有两种选择。

  1. 仅在 Consumerbin 目录中拥有 IExposedIface.dll 并为 AppDomain 处理 AppDomain.AssemblyResolve 事件,我将在其中创建 Exposed 的实例

  2. Consumerbin 目录以及每个Exposed.dll 旁边都有IExposedIface.dll

现在考虑我针对这个IExposedIface 构建Exposed

public interface IExposedIface
{
    string SaySomething();    
}

我针对这个IExposedIface 构建Consumer

public interface IExposedIface
{
    string SaySomething();
    string SaySomethingDifferent();
}

在第一种情况下,例外

例外:方法 'SaySomethingDifferent' 在类型 'Exposed.Exposed' 中来自 程序集 'Exposed, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' 没有实现

在我调用appDomain.CreateInstanceAndUnwrap(...) 以在新创建的AppDomain 中创建Exposed 的实例时抛出。

我觉得这很合理。

但在第二种情况下,appDomain.CreateInstanceAndUnwrap(...) 运行良好,我可以毫无问题地在检索到的对象上调用“SaySomething()”方法。一个例外

在接口/类型上找不到方法“SaySomethingDifferent”“IExposedIface.IExposedIface, IExposedIface, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null”。

仅当我在Consumer 中实际调用SaySomethingDifferent() 时才抛出。

我很惊讶在第二种情况下 CLR 让我走了这么远......有人可以解释为什么这是可能的吗?

【问题讨论】:

    标签: c# .net remoting appdomain .net-assembly


    【解决方案1】:
    1. 案例 #1 表示 Exposed.dll 绑定了错误版本的 IExposedIface.dll - 元数据加载器在加载程序集时能够检测到这一点,因为它找到了一个未实现的接口方法。

    2. 案例 #2(可能)意味着除了每个 Exposed.dll 之外,您还拥有每个 IExposedIface.dll 的正确版本,因此每个程序集都可以在其自己的 AppDomain 中加载。但是,AppDomain A 与 AppDomain B 的接口不同,这仅在调用实际跨越 AppDomain 边界时才会出现问题。

    我建议不要尝试那些二进制兼容性游戏,而是进行适当的版本控制(即,使用新方法创建一个新接口,从旧接口继承,所以新版本的 IExposedIface.dll 真的 向后兼容)。其他任何东西都真的很难调试,因为如果 Windows 可以访问 IExposedIface.dll 的 both 版本,你可能会意外地加载它们,然后你有两个版本的 Type在 AppDomain 中造成无穷无尽的麻烦 ;)

    【讨论】:

      猜你喜欢
      • 2014-02-02
      • 1970-01-01
      • 1970-01-01
      • 2012-12-03
      • 1970-01-01
      • 2016-01-06
      • 2012-11-04
      • 2023-04-01
      • 1970-01-01
      相关资源
      最近更新 更多