在我的情况下有三个组件:Consumer
类,IExposedIface
接口和Exposed
类实现IExposedIface
。 Consumer
和Exposed
都与IExposedIface
静态链接,但Consumer
没有编译时参考Exposed
。动态加载程序集:为什么此代码有效?
我想拿出一个方案,该方案将允许Consumer
在运行时加载不同版本的Exposed
(取决于输入数据 - 假设每个输入文件携带其中Exposed
版本应该被用来处理它的信息) 。为了实现这一点,我开始研究AppDomains,现在我有一个基本版本的工作。
到目前为止,在提供IExposedIface
组件到Exposed
组件时,有两种选择。
只在
Consumer
有IExposedIface.dll
的斌目录和处理AppDomain.AssemblyResolve
事件为AppDomain
中,我创建的Exposed
在
Consumer
有IExposedIface.dll
两个实例的斌目录以及每个Exposed.dll
。
现在考虑的是我建立Exposed
反对这种IExposedIface
:
public interface IExposedIface
{
string SaySomething();
}
和我建立Consumer
反对这种IExposedIface
:
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,版本= 2.0.0.0,文化=中性公钥=空'。
只有当我实际拨打电话号码为SaySomethingDifferent()
Consumer
。
我很惊讶,在这第二种情况下,CLR让我走了这么远......有人可以解释为什么这是可能的吗?