动态加载程序集:为什么此代码有效?

时间:2011-11-19 20:06:48

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

在我的情况下,有三个组件:Consumer类,IExposedIface接口和实现Exposed的{​​{1}}类。 IExposedIfaceConsumer都与Exposed静态链接,但IExposedIface没有Consumer的编译时引用。

我正在尝试提出一种方案,允许Exposed在运行时加载不同版本的Consumer(取决于输入数据 - 假设每个输入文档都包含有关{的哪个版本的信息{1}}应该用来处理它)。为此,我开始学习 AppDomains ,现在我的基本版本正在运行。

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

  1. 仅在IExposedIface bin 目录中设置Exposed,并为我正在创建的IExposedIface.dll处理Consumer事件AppDomain.AssemblyResolve

  2. 的一个实例
  3. AppDomain bin 目录中的Exposed以及每个IExposedIface.dll旁边的<{1}}。

  4. 现在考虑我针对此Consumer构建Exposed.dll

    Exposed

    我针对此IExposedIface构建了public interface IExposedIface { string SaySomething(); }

    Consumer

    在第一种情况下,例外

      

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

    在我致电IExposedIface以在新创建的 AppDomain 中创建public interface IExposedIface { string SaySomething(); string SaySomethingDifferent(); } 的实例时,会抛出

    这对我来说看起来很合理。

    但是在第二种情况下,appDomain.CreateInstanceAndUnwrap(...)完成得很好,我可以毫无问题地在检索到的对象上调用'SaySomething()'方法。例外

      

    在界面上找不到'SaySomethingDifferent'方法'IExposedIface.IExposedIface,IExposedIface,Version = 2.0.0.0,Culture = neutral,PublicKeyToken = null'。

    当我在Exposed中实际呼叫appDomain.CreateInstanceAndUnwrap(...)时,才会抛出

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

1 个答案:

答案 0 :(得分:0)

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

    < / LI>
  2. 案例#2(可能)意味着除了每个Exposed.dll之外,每个IExposedIface.dll都有正确版本,因此每个程序集都可以在其自己的AppDomain中加载。但是,AppDomain A具有与AppDomain B不同的接口,这只是当呼叫实际穿过AppDomain边界时的一个问题。

  3. 我建议不要尝试那些二进制兼容性游戏,而是做正确的版本控制(即用新方法创建一个新接口,继承旧接口,所以新版本的IExposedIface.dll 真的< / em>向后兼容)。其他任何东西真的难以调试,因为你可能会意外地加载两个版本的IExposedIface.dll(如果它们可以访问Windows),然后你有两个版本的类型在AppDomain中导致无故障;)