在我的情况下,有三个组件:Consumer
类,IExposedIface
接口和实现Exposed
的{{1}}类。 IExposedIface
和Consumer
都与Exposed
静态链接,但IExposedIface
没有Consumer
的编译时引用。
我正在尝试提出一种方案,允许Exposed
在运行时加载不同版本的Consumer
(取决于输入数据 - 假设每个输入文档都包含有关{的哪个版本的信息{1}}应该用来处理它)。为此,我开始学习 AppDomains ,现在我的基本版本正在运行。
到目前为止,在我看来,Exposed
程序集提供Exposed
时有两种选择。
仅在IExposedIface
的 bin 目录中设置Exposed
,并为我正在创建的IExposedIface.dll
处理Consumer
事件AppDomain.AssemblyResolve
AppDomain
的 bin 目录中的Exposed
以及每个IExposedIface.dll
旁边的<{1}}。
现在考虑我针对此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让我走了这么远......有人可以解释为什么这是可能的吗?
答案 0 :(得分:0)
案例#1表示Exposed.dll绑定了错误版本的IExposedIface.dll - 元数据加载器能够在加载程序集时检测到这一点,因为它找到了未实现的接口方法。
< / LI>案例#2(可能)意味着除了每个Exposed.dll之外,每个IExposedIface.dll都有正确版本,因此每个程序集都可以在其自己的AppDomain中加载。但是,AppDomain A具有与AppDomain B不同的接口,这只是当呼叫实际穿过AppDomain边界时的一个问题。
我建议不要尝试那些二进制兼容性游戏,而是做正确的版本控制(即用新方法创建一个新接口,继承旧接口,所以新版本的IExposedIface.dll 真的< / em>向后兼容)。其他任何东西真的难以调试,因为你可能会意外地加载两个版本的IExposedIface.dll(如果它们可以访问Windows),然后你有两个版本的类型在AppDomain中导致无故障;)