通过“四大行为”对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的扩展[实例篇]

作者:蒋金楠
微信公众账号:大内老A
微博:www.weibo.com/artech
如果你想及时得到个人撰写文章以及著作的消息推送,或者想看看个人推荐的技术资料,可以扫描左边二维码(或者长按识别二维码)关注个人公众号(原来公众帐号蒋金楠的自媒体将会停用)。
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

原文链接

时间: 2024-09-17 04:23:07

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

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

为了让读者对如何利用相应的行为对WCF进行扩展有个深刻的认识,在这里我提供一个简单的实例演示.本实例模拟的场景是这样的:我们创建一个支持多语言的资源服务,该服务旨在为调用者提供基于某种语言的文本型资源.但是,我们不希望客户端在每次调用服务的时候都显式地制定具体的语言,而是根据客户端服务调用线程表示语言文化的上下文来自动识别所需的语言.[源代码从这里下载] 要让资源服务具有识别语言文化的能够,我们必须将客户端服务调用线程当前的语言文化信息(具体来说就是Thread的两个属性:CurrentUICu

通过自定义ServiceHost实现对WCF的扩展[实例篇]

在<原理篇>中我们谈到了通过自定义ServiceHost对WCF进行扩展的本质,以及在IIS/WAS寄宿情况下ServiceHostFactory的作用.接下来通过一个具体的例子来演示如何通过WCF扩展实现以Unity为代表的IoC框架的集成,以及应用该扩展的ServiceHost和ServiceHostFactory如何定义.[源代码从这里下载] 目录 一.IoC/DI简介 步骤一.自定义InstanceProvider:UnityInstanceProvider 步骤二.创建服务行为:Un

[WCF权限控制]利用WCF自定义授权模式提供当前Principal[原理篇]

在<通过扩展自行实现服务授权>一文中,我通过自定义CallContextInitializer的方式在操作方法之前之前根据认证用户设置了当前线程的安全主体,从而实现授权的目的.实际上,WCF的安全体系本就提供相应的扩展,使你能够自由地实现安全主体的提供方式.具体来说,安全主体的提供可以通过自定AuthorizationPolicy或者ServiceAuthorizationManager来实现. 一.AuthorizationPolicy 在WCF安全应用编程接口中,所有的Authorizat

[WCF权限控制]WCF自定义授权体系详解[原理篇]

到目前为止,我么介绍的授权策略都是围绕着安全主体进行的,基本上都是基于角色的授权.虽然角色是定义权限最为常用的形式,但是它解决不了授权的所有问题.基于角色的授权策略一般是这样的:需要进行访问控制的操作或者资源关联到某个角色上,那么只要访问者被分配了该角色,就被授予了相应的权限.那么假设我们的授权策略是这样的:访问权限和两个角色进行关联,访问者需要同时被分配了这两个角色才能被授权.这是一个很常见的授权策略,但是典型的基于单一角色的授权解决不了这个问题(除非为两个角色的交集创建新的角色).而这仅仅是

[WCF 4.0新特性] 路由服务[原理篇]

在一个典型的服务调用场景中,具有两个基本的角色,即服务的消费者和服务的提供者.从消息交换的角度讲前者一般是消息的最初发送者,而后者则是消息的最终接收者.在很多情况下,由于网络环境的局限,消息的最初发送者和最终接收者不能直接进行消息交换,这就需要一个辅助实现消息路由的中介服务,这就是我们接下来要介绍的路由服务. 目录 一.路由服务就是一个WCF服务       路由服务契约的定义       路由服务契约的定义 二.基于消息内容的路由策略       RoutingBehavior服务行为    

走向DBA[MSSQL篇] 针对大表 设计高效的存储过程【原理篇】 附最差性能sql语句进化过程客串

原文:走向DBA[MSSQL篇] 针对大表 设计高效的存储过程[原理篇] 附最差性能sql语句进化过程客串 测试的结果在此处 本篇详解一下原理 设计背景 由于历史原因,线上库环境数据量及其庞大,很多千万级以上甚至过亿的表.目标是让N张互相关联的表 按照一张源表为基表,数据搬移归档 这里我们举例N为50 每张表数据5000W 最差性能sql进化客串 2表KeyName 字段意义 名称等相同 从bug01 表中取出前500条不在bug02 表中的数据 最差性能: SELECT TOP 500 a.K

详解WCF可扩展框架中的行为扩展

WCF以其灵活的可扩展架构为开发者提供了方便,其中对行为的扩展或许是应用中最为常见的.自定义 对行为的扩展并不复杂,但仍有许多细节需要注意. 在服务端,一般是对DispatchRuntime和DispatchOperation进行扩展,扩展点包括了对参数和消息的 检查,以及操作调用程序, 它们对应的接口分别为IParameterInspector,IDispatchMessageInspector 以及 IOperationInvoker.而在客户端,则是对ClientRuntime和Clien

如何解决分布式系统中的跨时区问题[原理篇]

一.场景以及需求 为了让大家本文介绍的主题有一个比较直观的认识,我们给出一个具体的应用场景.一个跨国公司开发一套统一的办公系统,供遍布全球的所有分公司使用.客户端的UI采用Smart Client (Windows Forms应用),而主要的业务逻辑均通过WCF服务的形式提供.我们将承载业务服务的服务器成为应用服务器,如右图(点击看大图)所示,应用服务器部属于中国境内(东8区).主要的客户端(分公司)分布于三个主要的国家和地区:北美.欧州和澳洲. 不论客户端和服务器之间,还是不同的客户端之间所处

Android 进程回收之LowMemoryKiller原理篇

在前面的文章Android进程保活一文中,对于LowMemoryKiller的概念做了简单的提及.LowMemoryKiller简称低内存杀死机制.简单来说,LowMemoryKiller(低内存杀手)是Andorid基于oomKiller原理所扩展的一个多层次oomKiller,OOMkiller(Out Of Memory Killer)是在Linux系统无法分配新内存的时候,选择性杀掉进程,到oom的时候,系统可能已经不太稳定,而LowMemoryKiller是一种根据内存阈值级别触发的内