通过“四大行为”对WCF的扩展[原理篇]

整个WCF框架由两个基本的层次构成,即服务模型层和信道层。对信道层的扩展主要通过针对绑定的扩展实现,具体来说就是自定义绑定元素,以及相关的信道管理器(信道监听器和信道工厂)、信道来改变对消息的处理和传输方式。

而对于服务模式型层的扩展则主要体现服务端和客户端运行时框架的定制,进而让WCF按照我们希望的方式进行运作。由于整个运行时框架由一系列的可扩展组件构成,并且大部分运行时属性也可以改写,所以针对服务模型层的扩展具体体现在:根据具体的需要定义相应的组件,并以某种情形将这些自定义的组件应用到运行时框架相应的地方,或者按照我们希望的方式定制相应的运行时属性。

而WCF为我们提供两种典型的应用自定义组件或者修改运行时属性的形式,即通过定义相应的行为(服务行为、终结点行为、契约行为和操作行为)和自定义ServiceHost,我们也把它们称为WCF的两种扩展形式。我们先来介绍WCF的四大行为。

一、WCF四种类型的行为

作为最为常用的扩展方式,WCF的四大行为的使用主要体现在两个方面:其一、WCF自身提供的很多特性和功能是通过行为的方式来实现的;其二、作为使用WCF的应用,可以通过自定义的行为来实现解决具体问题的扩展。

根据应用目标的范围的不同,WCF具有四种类型的行为:服务行为、终结点行为、契约行为和操作行为,它们的名称体现了行为本身的作用范围。对于WCF的这四种行为,读者肯定不会感到陌生。因为WCF提供的很多功能和特性都是通过相应的行为来实现的。不过,为了让读者对行为的本质有一个深刻的认识,能够帮助读者能够选择正确的行为类型来实现扩展,我们对WCF的四大行为作一个系统的介绍。

对于WCF的四种类型的行为,它们均具有各自接口。除了服务行为只是应用于服务端之外,终结点行为、契约行为和操作行为都可以同时应用于服务端和客户端。所以后者具有相同的方法定义。

   1: public interface IEndpointBehavior
   2: {
   3:     void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters);
   4:     void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime);
   5:     void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher);
   6:     void Validate(ServiceEndpoint endpoint);
   7: }
   8:  
   9: public interface IContractBehavior
  10: {
  11:     void AddBindingParameters(ContractDescription contractDescription, ServiceEndpoint endpoint, BindingParameterCollection bindingParameters);
  12:     void ApplyClientBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, ClientRuntime clientRuntime);
  13:     void ApplyDispatchBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, DispatchRuntime dispatchRuntime);
  14:     void Validate(ContractDescription contractDescription, ServiceEndpoint endpoint);
  15: }
  16: public interface IOperationBehavior
  17: {
  18:     void AddBindingParameters(OperationDescription operationDescription, BindingParameterCollection bindingParameters);
  19:     void ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation);
  20:     void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation);
  21:     void Validate(OperationDescription operationDescription);
  22: }

上面的代码给出了基于终结点行为、契约行为和操作行为相应接口的定义,从中我们可以看到它们具有四个相同的方法。

  • Validate:验证相应的描述(ServiceEndpoint、ContractDescription和OperationDescription)是否符合要求;
  • AddBindingParameters:向绑定上下文中添加相应的绑定参数,这些参数一般提供给自定义的绑定元素,并最终被相应的信道获取以控制对消息的操作;
  • ApplyDispatchBehavior:将扩展应用到服务端分发运行时;
  • ApplyClientBehavior:将扩展应用到客户端运行时。

由于服务行为仅仅提供针对服务端的扩展实现,所以基于服务行为的接口并没有定义ApplyClientBehavior方法,下面的代码片断提供了服务行为接口IServiceBehavior的定义。

   1: public interface IServiceBehavior
   2: {
   3:     void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, 
   4: Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters);
   5:     void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase);
   6:     void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase);
   7: }

二、行为方法的执行

WCF四种类型的行为都属于是“服务描述”的范畴,所以ServiceDescriptionServiceEndpointContractDescriptionOperationDescription均具有一个Behaviors的属性。如下面的代码片断所示,这些属性的类型都是KeyedByTypeCollection<T>,而泛型类型分别为上述的四个行为接口。

   1: public class ServiceDescription
   2: {
   3:     //其他成员
   4:     public KeyedByTypeCollection<IServiceBehavior> Behaviors { get; }
   5: }
   6: public class ServiceEndpoint
   7: {
   8:     //其他成员 
   9:     public KeyedByTypeCollection<IEndpointBehavior> Behaviors { get; }
  10: }
  11: public class ContractDescription
  12: {
  13:     //其他成员
  14:     public KeyedByTypeCollection<IContractBehavior> Behaviors { get; }
  15: }
  16: public class OperationDescription
  17: {  
  18:     //其他成员
  19:     public KeyedByTypeCollection<IOperationBehavior> Behaviors { get; }
  20: }

如果要理解此四种类型的行为是如何实现对WCF的扩展的,就必须了解定义在行为中的这些方法执行的时机。那么我们就来谈论一下这些行为方法在服务端和客户端究竟是在什么时候执行的。

在进行服务寄宿的时候,与寄宿服务相关的所有类型行为的Validate,AddBindingParameters和ApplyDispatchBehavior都是在ServiceHost开启的时候被执行的。而此时,表示服务描述的ServiceDescription对象已经在初始化ServiceHost的时候被成功创建。具体来说,此三个方法执行的先后顺序是先执行Validate方法、然后执行AddBindingParameters方法,最后执行ApplyDispatchBehavior方法。而执行此三个方法的方式都是类似的:

  • 通过ServiceDescription的Behaviors得到所有服务行为,并执行每个服务行为的方法;
  • 通过ServiceDescription的Endpoints属性得到服务具有的所有终结点,针对每个表示终结点的ServiceEndpoint对象,通过其Behaviors属性得到所有终结点行为,并执行终结点行为的方法;
  • 针对每一个表示终结点的ServicePoint对象,通过Contract属性得到表示服务契约描述的ContractDescription对象。通过其Behaviors得到所有的契约行为,并调用每个契约行为的方法;
  • 针对每一个表示服务契约描述的ContractDescription对象,通过其Operations属性得到服务契约所有的操作。针对每个表示操作描述的OperationDescription对象,通过其Behaviors属性得到所有的操作行为,并调用每个操作行为的方法。

对于客户端来说,三个行为(不包括服务行为)的三个方法会在创建的ChannelFactory<TChannel>开启的时候执行。具体的执行顺序为此三个方法执行的先后顺序是先执行Validate方法、然后执行AddBindingParameters方法,最后是执行ApplyClientBehavior方法,其执行的方式和服务端完全一致。

通过“四大行为”对WCF的扩展[原理篇] 通过“四大行为”对WCF的扩展[实例篇]

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏猛牛哥的博客

aardio v13.6 更新

1502
来自专栏orientlu

FreeRTOS 消息队列

上面这几中方式中, 除了消息通知, 其他几种实现都是基于消息队列。消息队列作为主要的通信方式, 支持在任务间, 任务和中断间传递消息内容。 这一章介绍 Fre...

4792
来自专栏mwangblog

python操作文本文件

1974
来自专栏Ryan Miao

java基础题目总结

有些基础题目由于工作中用的比较少但却又是不可少的,这样回答起来就会反应慢,不确定,不准确,特此开了文章记录遇到的不确定或者回答比较拗口的问题。 1.servle...

3569
来自专栏python学习路

二、路由、模板

一、路由系统 在settings.py文件中通过ROOT_URLCONF指定根级url的配置 urlpatterns是一个url()实例的列表 一个url()对...

3408
来自专栏大内老A

WCF客户端运行时架构体系详解[上篇]

客户端调用WCF服务的方式不外乎有两种:其一、通过代码生成工具(比如SvcUtil.exe)导入服务的元数据生成服务代理相关的类型;其二、通过ChannelFa...

18110
来自专栏idba

浅谈 multiprocessing

一前言 使用python进行并发处理多台机器/多个实例的时候,我们可以使用threading ,但是由于著名的GIL存在,实际上threading 并...

940
来自专栏haifeiWu与他朋友们的专栏

Redis协议规范(译文)

Redis客户端使用名为RESP(Redis序列化协议)的协议与Redis服务器进行通信。 虽然该协议是专为Redis设计的,但它可以用于其他CS软件项目的通讯...

1683
来自专栏大内老A

[WCF安全系列]绑定、安全模式与客户端凭证类型:WSHttpBinding与WSDualHttpBinding

在上一篇文章中,我们详细地介绍了BasicHttpBinding具有怎样的安全模式的支持,已经在各种安全模式下分别可以采用怎样的客户端凭证。接下来我们来进一步分...

2047
来自专栏Android 研究

Android系统启动——3init.rc解析

init.rc文件是以“块”(section)为单位服务的,,一个“块”(section)可以包含多行。“块”(section)分成两大类:一类称为"动作(ac...

4572

扫码关注云+社区

领取腾讯云代金券