调度程序负责从基础通道中拉取传入消息,将其转换为应用程序代码中的方法调用,并将结果发送回调用方。 调度程序扩展允许修改此处理。 可以实现检查或修改消息或参数内容的消息或参数检查器。 您可以更改消息路由到操作的方式,或提供其他某些功能。
本主题介绍如何在 Windows Communication Foundation(WCF)服务应用程序中使用 DispatchRuntime 类和 DispatchOperation 类,以修改调度程序的默认执行行为,或者在通过通道层发送或检索消息、参数或返回值之前或之后,截获或修改它们。 有关等效客户端运行时消息处理的详细信息,请参阅 扩展客户端。 若要了解类型在访问各种运行时自定义对象之间的共享状态时所扮演的角色 IExtensibleObject<T> ,请参阅 可扩展对象。
调度员
服务模型层执行开发人员编程模型与基础消息交换之间的转换,通常称为通道层。 在 WCF 中,通道和终结点调度程序(ChannelDispatcher 以及 EndpointDispatcher分别)是负责接受新通道、接收消息、作调度和调用以及响应处理的服务组件。 调度程序对象是接收方对象,但双工服务中的回调协定实现还公开其用于检查、修改或扩展的调度程序对象。
通道调度程序(与之配合的 IChannelListener)将消息从底层通道中拉出,并将消息传递给各自的终结点调度程序。 每个终结点调度程序都有一个 DispatchRuntime,用于将消息路由到相应的、负责调用实现操作的方法的 DispatchOperation。 同时调用各种可选和必需的扩展类。 本主题介绍如何将这些部分组合在一起,以及如何修改属性并插入自己的代码来扩展基本功能。
通过使用服务、终结点、协定或操作行为对象插入调度程序属性和修改的自定义对象。 本主题不介绍如何使用行为。 有关用于插入调度程序修改的类型的详细信息,请参阅 “使用行为配置和扩展运行时”。
下图提供了服务中体系结构项的高级视图。
通道调度程序
创建 ChannelDispatcher 对象以将特定 URI(称为侦听 URI)处的 IChannelListener 与服务的实例相关联。 每个 ServiceHost 对象可以有多个 ChannelDispatcher 对象,每个对象仅与一个侦听器和侦听 URI 相关联。 消息到达时,ChannelDispatcher 将查询每个关联的 EndpointDispatcher 对象,以确定该终结点是否可以接受消息,并将消息传递给可以接收的终结点。
控制通道会话生存期和行为的所有属性都可用于检查或修改 ChannelDispatcher 对象。 这些属性包括自定义通道初始值设定项、通道侦听器、主机、关联的 InstanceContext,等等。
终结点调度程序
该EndpointDispatcher对象负责处理来自ChannelDispatcher的消息,当消息的目标地址与AddressFilter匹配且消息动作与ContractFilter属性匹配时。 如果两 EndpointDispatcher 个对象可以接受消息, FilterPriority 属性值将确定更高的优先级终结点。
使用EndpointDispatcher来获取两个主要服务模型扩展点——DispatchRuntime类和DispatchOperation类,这可以用于自定义调度程序的处理。 该 DispatchRuntime 类允许用户在合约范围内拦截和扩展分发器(即合约中的所有消息)。 DispatchOperation 类允许用户在操作范围内(即,针对操作中的所有消息)截获并扩展调度程序。
情境
可以有很多理由来扩展调度程序:
自定义消息验证。 用户可以强制消息对特定架构有效。 这可以通过实现消息拦截器接口来实现。 有关示例,请参阅 消息检查器。
自定义消息日志记录。 用户可以检查和记录一组流经终结点的应用程序消息。 也可以使用消息拦截器接口完成此作。
自定义消息转换。 用户可以对运行时中的消息应用某些转换(例如,用于版本控制)。 这可以通过消息拦截器接口再次完成。
自定义数据模型。 用户可以使用除了 WCF 默认支持的System.Runtime.Serialization.DataContractSerializer、System.Xml.Serialization.XmlSerializer和原始消息等数据序列化模型以外的其他数据序列化模型。 这可以通过实现消息格式化程序接口来完成。 有关示例,请参阅 操作格式化器和操作选择器。
自定义参数验证。 用户可以强制类型化参数有效(而不是 XML)。 可以使用参数检查器接口完成此作。
自定义操作调度。 用户可以在操作以外的内容上实现调度,例如在正文元素或自定义消息属性上。 可以使用 IDispatchOperationSelector 接口完成此操作。 有关示例,请参阅 操作格式化器和操作选择器。
对象池。 用户可以池实例,而不是为每个调用分配一个新实例。 这可以使用实例提供程序接口实现。 有关示例,请参阅 Pooling。
实例租约。 用户可以实现实例生存期的租约模式,类似于 .NET Framework 远程处理的租约模式。 可以使用实例上下文生存期接口完成此操作。
自定义错误处理。 用户可以控制如何处理本地错误,以及如何将错误传达回客户端。 可以使用IErrorHandler接口来实现这个。
自定义授权行为。 用户可以通过扩展合约或操作运行时组件,在消息中存在的令牌基础上添加安全检查,以实现自定义访问控制。 这可以使用消息拦截器或参数侦听器接口来实现。 有关示例,请参阅 安全扩展性。
谨慎
由于更改安全属性有可能损害 WCF 应用程序的安全性,因此强烈建议在部署之前谨慎和测试与安全相关的修改。
自定义 WCF 运行时验证程序。 可以安装用于检查服务、协定和绑定的自定义验证程序,以针对 WCF 应用程序强制实施企业级策略。 (例如,请参阅 如何在企业中锁定端点。)
使用 DispatchRuntime 类
使用 DispatchRuntime 类可修改服务或单个终结点的默认行为,或将实现自定义修改的对象插入到以下一个或全部两个服务进程中(对于双工客户端则为客户端进程):
将传入消息转换为对象,并将这些对象以方法调用的形式在服务对象中执行。
将响应服务操作调用后收到的对象转换为出站消息。
通过 DispatchRuntime,即使在无法识别消息的情况下,您也可以为特定协定中的所有消息截获和扩展通道或终结点调度程序。 当到达的消息与协定中声明的任何消息均不匹配时,就会将该消息调度到由 UnhandledDispatchOperation 属性返回的操作。 若要截获或扩展针对特定操作的所有消息,请参见 DispatchOperation 类。
DispatchRuntime 类公开了四个主要的调度器可扩展性方面。
通道组件利用DispatchRuntime的属性和ChannelDispatcher属性返回的相关联的通道调度程序的属性,以自定义通道调度程序接受和关闭通道的方式。 此类别包括 ChannelInitializers 属性和 InputSessionShutdownHandlers 属性。
可为处理的每个消息自定义消息组件。 此类别包括MessageInspectors、OperationSelectorOperations属性和ErrorHandlers属性。
实例组件自定义服务类型的实例的创建、生存期和处置。 有关服务对象生存期的详细信息,请参阅 InstanceContextMode 属性。 此类别包括 InstanceContextInitializers 属性和 InstanceProvider 属性。
与安全相关的组件可以使用以下属性:
SecurityAuditLogLocation 指示写入审核事件的位置。
ImpersonateCallerForAllOperations 可控制服务是否尝试使用传入消息所提供的凭据进行模拟。
MessageAuthenticationAuditLevel 控制是否成功将消息身份验证事件写入到指定的 SecurityAuditLogLocation事件日志中。
PrincipalPermissionMode 控制属性 CurrentPrincipal 的设置方式。
ServiceAuthorizationAuditLevel 指定如何执行授权事件的审核。
SuppressAuditFailure 指定是否禁止在日志记录过程中发生的非关键异常。
通常,自定义扩展对象被分配给DispatchRuntime属性,或者由服务行为(实现IServiceBehavior的对象)、协定行为(实现IContractBehavior的对象)或终结点行为(实现IEndpointBehavior的对象)插入到集合中。 然后,将安装行为对象添加到适当的行为集合中,可以通过编程方式或通过实现自定义 BehaviorExtensionElement 对象来实现,以便使用应用程序配置文件插入该行为。
双工客户端(实现双工服务指定的回调协定的客户端)也具有一个 DispatchRuntime 对象,该对象可以通过 CallbackDispatchRuntime 属性进行访问。
使用 DispatchOperation 类
该 DispatchOperation 类是运行时修改的位置,也是仅限于一个服务操作的自定义扩展的插入点。 (若要修改协定中所有消息的服务运行时行为,请使用 DispatchRuntime 类。
使用自定义服务行为对象安装 DispatchOperation 修改。
使用 Operations 属性查找表示特定服务操作的 DispatchOperation 对象。
以下属性控制操作级别的运行时执行:
Action、ReplyAction、FaultContractInfos、IsOneWay、IsTerminating和Name属性获取操作的相应值。
这些ReleaseInstanceBeforeCall和ReleaseInstanceAfterCall属性控制用户定义服务对象相对于InstanceContext的生存期。
DeserializeRequest属性、SerializeReply属性和Formatter属性允许显式控制消息到对象和对象到消息的转换。
该 Impersonation 属性指定操作模拟级别。
该 CallContextInitializers 属性为操作插入自定义调用上下文扩展。
属性 AutoDisposeParameters 控制何时销毁参数对象。
用于插入自定义调用程序对象的 Invoker 属性。
使用该 ParameterInspectors 属性可以插入可用于检查或修改参数和返回值的自定义参数检查器。