可扩展对象
可扩展对象模式用于使用新功能扩展现有运行时类,或者向对象中添加新状态。附加到可扩展对象之一的扩展名,在访问附加到公共可扩展对象的共享状态和功能过程的各个不同阶段启用行为,各可扩展对象可以访问该公共扩展对象。
IExtensibleObject<T> 模式
可扩展对象模式中有三种接口:IExtensibleObject、IExtension 和 IExtensionCollection。
IExtensibleObject 接口通过允许 IExtension 对象自定义类型的功能的这些类型实现。
可扩展对象允许动态聚合 IExtension 对象。IExtension 对象的特征体现在以下接口上:
public interface IExtension<T>
where T : IExtensibleObject<T>
{
void Attach(T owner);
void Detach(T owner);
}
类型限制保证仅为是 IExtensibleObject 的类定义扩展名。Attach 和 Detach 提供聚合或解聚的通知。
对于实现限制它们何时可能会添加到所有者中或从所有者中移除有效。例如,可以完全禁止移除(这将禁止在所有者或扩展名处于某个特定状态时添加或移除扩展名)、禁止同时添加多个所有者,或者仅允许单个移除后进行单个添加。
IExtension 不表示与其他标准托管接口进行的任何交互。具体地说,所有者对象上的 System.IDisposable.Dispose 方法通常不与它的扩展名分离。
将扩展名添加到集合中时,在 Attach 进入该集合前调用它。从集合中移除扩展名时,在移除 Detach 后调用它。这意味着(假设适当同步)当扩展名介于 Attach 和 Detach 之间时,仅可以在集合中找到它。
传递给 FindAll 或 Find 的对象不需要是 IExtension(例如,可以传递任何对象),但返回的扩展名是 IExtension。
如果集合中的扩展名不为 IExtension,则 Find 返回 null,并且 FindAll 返回一个空集合。如果多个扩展名实现 IExtension,则 Find 返回其中一个扩展名。从 FindAll 中返回的值是快照。
有两种主要方案。第一个方案使用 Extensions 属性作为基于类型的字典插入对象状态,以使另一组件使用该类型进行查找。
第二个方案使用 Attach 和 Detach 属性使对象可以参与自定义行为,例如注册事件、监视状态转换等。
IExtensionCollection 接口是 IExtension 对象的集合,这些对象允许按其类型检索 IExtension。System.ServiceModel.IExtensionCollection.Find 返回最近添加的对象,该对象是该类型的 IExtension。
Windows Communication Foundation 中的可扩展对象
Windows Communication Foundation (WCF) 中包含四个可扩展对象:
ServiceHostBase — 这是服务主机的基类。此类的扩展名可用于扩展 ServiceHostBase 自身的行为,或者用于存储每个服务的状态。
InstanceContext — 此类将服务类型的实例与服务运行时相连。它包含有关该实例的信息以及对 InstanceContext 的包含 ServiceHostBase 的引用。此类的扩展名可用于扩展 InstanceContext 的行为,或者用于存储每个服务的状态。
OperationContext — 此类表示为每个操作收集的运行时的操作信息。这包括的信息有:传入消息头、传入消息属性和传入安全标识,以及其他信息。此类的扩展名可以扩展 OperationContext 的行为,也可以存储每个操作的状态。
IContextChannel — 此接口允检查 WCF 运行时生成的通道和代理的每个状态。此类的扩展名可以扩展 IClientChannel 的行为,也可以使用它存储每个通道的状态。
下面的代码示例演示使用简单的扩展名来跟踪 InstanceContext 对象。