整个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四种类型的行为都属于是“服务描述”的范畴,所以ServiceDescription、ServiceEndpoint、ContractDescription和OperationDescription均具有一个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方法,其执行的方式和服务端完全一致。
作者:蒋金楠
微信公众账号:大内老A
微博:www.weibo.com/artech
如果你想及时得到个人撰写文章以及著作的消息推送,或者想看看个人推荐的技术资料,可以扫描左边二维码(或者长按识别二维码)关注个人公众号(原来公众帐号蒋金楠的自媒体将会停用)。
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。