协定、视图和适配器
本主题介绍视图和适配器,即外接程序管线的两端常用管线段,以及宿主和外接程序都使用的协定。 下面的插图显示了外接程序管线的管线段。
外接程序管线
有关代码示例,请参见演练:在宿主发生变化时启用向后兼容性和演练:在宿主和外接程序之间传递集合。
协定
开发通信管线的第一步是定义一个必须从 IContract 接口派生的协定。 如果宿主和外接程序加载到不同的应用程序域中,则管线的外接程序端与管线的宿主端之间会存在一个隔离边界。 协定是一个非版本控制接口,它可以定义协议以便跨隔离边界传送类型。 通过使用协定跨隔离边界进行通信,外接程序模型可以防止宿主和外接程序的类型的实现跨边界泄漏或引发版本管理问题。
必须跨应用程序域传送的对象必须是可远程处理的对象。 有关可远程处理的对象的更多信息,请参见Remotable and Nonremotable Objects。
ContractBase 类提供 IContract 成员的默认实现。 协定接口也可以继承此类。
协定要求
协定必须遵从一组要求,以确保在协定内表示的所有类型都是安全的、可进行版本控制并且可以跨宿主和外接程序之间的隔离边界传递。
协定必须从 IContract 继承并且必须仅使用下列类型:
从 IContract 派生的其他协定。
基元数据类型:整数和布尔值类型。
在协定程序集中定义的可序列化类型。
密封的可序列化引用类型。 例如,可以通过隔离边界传递一个 String 对象,因为该对象是一个密封的可序列化引用类型。
在协定或 Mscorlib.dll 中定义的枚举。
AddInToken 对象。
上面列出的任何类型的数组(除协定数组外)。
若要传递对象集合,请使用实现泛型 IList<T> 接口的类型,例如 List<T> 和 ArrayList 集合。 若要跨隔离边界传递这些集合,请暂时将它们转换为 IListContract<T> 接口。 主题演练:在宿主和外接程序之间传递集合演示如何传递集合。
若要构造管线,必须使用 AddInContractAttribute 特性标识表示外接程序的协定。
管线开发过程的下一步是为管线的两端创建视图段和适配器段。 这些段为宿主应用程序和外接程序提供其各自对象模型的视图,并提供在这些视图与协定之间进行转换的适配器。
视图
宿主的外接程序视图和外接程序的宿主视图是包含接口或抽象类的程序集,这些接口或抽象类表示外接程序和宿主各自的视图以及在它们之间流动的类型的视图。 视图不依赖于用来在它们之间通信的协定。 视图还将外接程序及宿主与其各自的实现分开。 这样就可以在不影响宿主或外接程序的情况下更改适配器和协定。
为了构造管线,外接程序实现或继承的外接程序视图中的类型由 AddInBaseAttribute 特性标识,称为外接程序基。 宿主视图不需要特性来获得可发现性,因为宿主视图是传递给 FindAddIns 方法的。
适配器
外接程序端适配器和宿主端适配器是包含适配器类的程序集,这些适配器类用于在视图和协定之间执行转换。 术语“端”是指管线上适配器所在的一端。 根据调用的方向,适配器将视图转换为协定或者将协定转换为视图。 如果进行两个方向上的调用(即宿主调用外接程序并且外接程序调用宿主),则管线的每一端都将有两个适配器。 因此,有两种类型的适配器:
“视图到协定”适配器。
适配器程序集中将视图转换为协定的类。 此类通过调用传递给其构造函数的视图来实现协定并作为协定跨边界进行封送。 此类必须继承 ContractBase 并实现协定。
“协定到视图”适配器。
适配器程序集中将协定转换为视图的类。 根据视图是接口还是抽象基类型,此类实现或继承它要转换的视图段,并通过调入传递给适配器的构造函数的协定来实现视图的成员。
为了构造管线,必须通过应用 AddInAdapterAttribute 特性来标识外接程序端适配器类,并通过应用 HostAdapterAttribute 特性来标识宿主端适配器类。
不要求适配器是公共的。