接口和后期在C#绑定(Interfaces and Late Binding in C#)

2019-10-17 10:36发布

我在C#这样做之前的插件系统的正常工作,这就是为什么我很困惑,为什么这个新的,独立的插件系统不工作我所期望的方式。

我有我的插件组装 - 我们称之为“plugin.dll”我有我的主要部件 - 姑且称之为APP.EXE。

我有一个名为接口IMyObject及其实现, MyObject无一不是在plugin.dll定义。 我已经复制了确切的代码文件IMyObject (该插件开发者提供给我)到我的主要APP.EXE组装。

我得到一个InvalidCastException ,当我尝试我加载使用反射对象映射到该对象实现的接口。 我知道对象实现它,因为

t.GetInterface(typeof(IMyObject).FullName) != null

是真的。 我还可以浏览MyObject在Visual Studio中的对象资源管理器,我可以看到它实现IMyObject

这里的地方出了问题:

 if (ifaceType != null)
 {
    ConstructorInfo constructor = ifaceType.GetConstructor(new Type[] { });

    if (constructor != null)
    {

       object obj = constructor.Invoke(null); // this works - obj is assigned an 
                                              // instance of MyObject

       IMyObject myObj = (IMyObject)obj;      // triggers InvalidCastException
    }               
 }

我可以什么我现在做的和我之前实施这种方式之间看到的唯一区别接口是两个独立的组件定义 (即使代码文件是相同的,它们属于同一个命名空间)。

这是我的麻烦的原因是什么? 如果是这样,我怎么可以连接到我的插件没有在编译时链接,并使用在插件本身定义的接口?

我要补充的是,除了界面,我没有访问该插件的源代码。

Answer 1:

尽管这些接口有相同的代码,它们是两个不同的组件(你可以打印他们AssemblyQualifiedNames,看到了差距)两个独立的接口。



Answer 2:

是的,接口由运行时考虑不同的类型。 他们是所有相同的名称。

有没有办法用在宿主程序的界面,而不反射,因为你不能静态地反对它链接。 通常情况下,一个把接口的插件主机组件和插件实现它们,而不是相反。



Answer 3:

在.NET扩展应用程序的典型骨架由这些组件的:

  • 合同装配。 这其中包含合同(只是接口和,任选地,一些数据契约,在接口中使用)为插件,和合同主机;
  • 主机装配。 这其中包含了主合同的实现和从第一个依赖;
  • 几个插件组件。 这些组件包含插件合同实现,并从第一个过于依赖。

因此,使用合同组装,你实现,该主机和插件是相互独立的(所以,插件后期绑定),但他们有共同的合同,在编译时双方(插件和主机)闻名。

你会(定义插件接触多次)的方式是错误的方式。



Answer 4:

正如其他人所说的是两种不同的接口,来处理这个正确的方法是将定义为第三大会,两个参考。

但是...有一种方式来获得这种通过使用一种称为库工作即兴接口 。



文章来源: Interfaces and Late Binding in C#