WCF扩展系列 - 行为扩展(Behaviors)

        这个系列的第一部分将会重点关注WCF行为(behaviors),WCF提供了四种类型的行为:服务行为、终结点行为、契约行为和操作行为。这些行为的接口几乎是所有WCF的扩展入口。本篇文章只是对行为拓展讲述一些基础的铺设,具体到上面四个行为的扩展以及使用案例,将会在后续的文章中讲到.

Behaviors

上述这四个行为的所定义的接口分别是IServiceBehavior,IEndpointBehavior,IContractBehavior以及 IOperationBehavior。虽然是四个不同的接口,但它们的接口方法却基本相同,分别为 AddBindingParameters(),ApplyClientBehavior()以及ApplyDispatchBehavior()。注意,IServiceBehavior由于只能作用在服务端,因此并不包含ApplyClientBehavior()方法

public interface I[Service/Endpoint/Contract/Operation]Behavior {
                void Validate(DescriptionObject);
                void AddBindingParameters(DescriptionObject, BindingParameterCollection);
                void ApplyDispatchBehavior(DescriptionObject, RuntimeObject);
                void ApplyClientBehavior(DescriptionObject, RuntimeObject); // not on IServiceBehavior
}

其中的方法描述如下:

  • AddBindingParameters用于向绑定元素传递自定义数据,以支持协定实现。
  • Validate:用于检查服务宿主和服务说明,从而确定服务是否可成功运行。
  • Apply[Client/Dispatch]Behavior这是我们可以引用和修改WCF运行时对象的地方,也是用得最多的行为方法(大部分情况,上两个方法都会留空)。用于更改运行时属性值或插入自定义扩展对象(例如错误处理程序、消息或参数拦截器、安全扩展以及其他自定义扩展对象)。

他们各自的作用范围如下图所示(引用自张逸):

image

 

增加一个行为(behaviors )

向WCF中增加行为有三种不同的方法:

    • 代码:service / endpoint / contract / operation 的描述类有一个behaviors集合属性,我们可以通过他简单的增加一个行为,具体做法,先将自定义服务行为添加到 Behaviors 属性,然后对 System.ServiceModel.ServiceHost 对象调用 ICommunicationObject.Open 方法。

    • 配置文件:通过配置文件system.serviceModel/behaviors 节点,我们可以指定service behaviors 和 endpoint behaviors,已达到添加行为的目的

    • 特性: 添加行为的简单方法是使用特性 — — 除了终结点行为。通过创建特性类 (基类型 = = System.Attribute) 和实现其中一个行为接口,您可以将特性应用于适当的元素,并添加行为到元素的描述。下面的代码显示了一个简单的服务,基于特性的行为的添加以及输出它们的调用顺序 (以及通过代码添加终结点行为)。

View Code
using  System;
using  System.Collections.ObjectModel;
using  System.Reflection;
using  System.ServiceModel;
using  System.ServiceModel.Channels;
using  System.ServiceModel.Description;
using  System.ServiceModel.Dispatcher;

namespace  Behaviors
{
class  MyServiceBehaviorAttribute : Attribute, IServiceBehavior
{
public   void  AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection < ServiceEndpoint >  endpoints, BindingParameterCollection bindingParameters)
{
Console.WriteLine(
" Inside {0}.{1} " this .GetType().Name, MethodBase.GetCurrentMethod().Name);
}

public   void  ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
Console.WriteLine(
" Inside {0}.{1} " this .GetType().Name, MethodBase.GetCurrentMethod().Name);
}

public   void  Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
Console.WriteLine(
" Inside {0}.{1} " this .GetType().Name, MethodBase.GetCurrentMethod().Name);
}
}

class  MyEndpointBehavior : IEndpointBehavior
{
public   void  AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
{
Console.WriteLine(
" Inside {0}.{1}, endpoint {2} " this .GetType().Name, MethodBase.GetCurrentMethod().Name, endpoint.Name);
}

public   void  ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
Console.WriteLine(
" Inside {0}.{1}, endpoint {2} " this .GetType().Name, MethodBase.GetCurrentMethod().Name, endpoint.Name);
}

public   void  ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{
Console.WriteLine(
" Inside {0}.{1}, endpoint {2} " this .GetType().Name, MethodBase.GetCurrentMethod().Name, endpoint.Name);
}

public   void  Validate(ServiceEndpoint endpoint)
{
Console.WriteLine(
" Inside {0}.{1}, endpoint {2} " this .GetType().Name, MethodBase.GetCurrentMethod().Name, endpoint.Name);
}
}

class  MyContractBehaviorAttribute : Attribute, IContractBehavior
{
public   void  AddBindingParameters(ContractDescription contractDescription, ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
{
Console.WriteLine(
" Inside {0}.{1}, contract {2} " this .GetType().Name, MethodBase.GetCurrentMethod().Name, contractDescription.ContractType.Name);
}

public   void  ApplyClientBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
Console.WriteLine(
" Inside {0}.{1}, contract {2} " this .GetType().Name, MethodBase.GetCurrentMethod().Name, contractDescription.ContractType.Name);
}

public   void  ApplyDispatchBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, DispatchRuntime dispatchRuntime)
{
Console.WriteLine(
" Inside {0}.{1}, contract {2} " this .GetType().Name, MethodBase.GetCurrentMethod().Name, contractDescription.ContractType.Name);
}

public   void  Validate(ContractDescription contractDescription, ServiceEndpoint endpoint)
{
Console.WriteLine(
" Inside {0}.{1}, contract {2} " this .GetType().Name, MethodBase.GetCurrentMethod().Name, contractDescription.ContractType.Name);
}
}

class  MyOperationBehaviorAttribute : Attribute, IOperationBehavior
{
public   void  AddBindingParameters(OperationDescription operationDescription, BindingParameterCollection bindingParameters)
{
Console.WriteLine(
" Inside {0}.{1}, operation {2} " this .GetType().Name, MethodBase.GetCurrentMethod().Name, operationDescription.Name);
}

public   void  ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation)
{
Console.WriteLine(
" Inside {0}.{1}, operation {2} " this .GetType().Name, MethodBase.GetCurrentMethod().Name, operationDescription.Name);
}

public   void  ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation)
{
Console.WriteLine(
" Inside {0}.{1}, operation {2} " this .GetType().Name, MethodBase.GetCurrentMethod().Name, operationDescription.Name);
}

public   void  Validate(OperationDescription operationDescription)
{
Console.WriteLine(
" Inside {0}.{1}, operation {2} " this .GetType().Name, MethodBase.GetCurrentMethod().Name, operationDescription.Name);
}
}

[ServiceContract]
[MyContractBehavior]
public   interface  ITest
{
[OperationContract]
[MyOperationBehavior]
int  Add( int  x,  int  y);
[OperationContract]
int  Multiply( int  x,  int  y);
}

[ServiceContract]
[MyContractBehavior]
public   interface  ITest2
{
[OperationContract]
[MyOperationBehavior]
string  Echo( string  text);
}

[MyServiceBehavior]
public   class  Service : ITest, ITest2
{
public   int  Add( int  x,  int  y) {  return  x  +  y; }
public   int  Multiply( int  x,  int  y) {  return  x  *  y; }
public   string  Echo( string  text) {  return  text; }
}

class  Program
{
static   void  Main( string [] args)
{
string  baseAddress  =   " http:// "   +  Environment.MachineName  +   " :8000/Service " ;
ServiceHost host 
=   new  ServiceHost( typeof (Service),  new  Uri(baseAddress));
ServiceEndpoint ep1 
=  host.AddServiceEndpoint( typeof (ITest),  new  BasicHttpBinding(),  " basic " );
ep1.Name 
=   " Endpoint1-BasicHttp " ;
ep1.Behaviors.Add(
new  MyEndpointBehavior());
ServiceEndpoint ep2 
=  host.AddServiceEndpoint( typeof (ITest2),  new  WSHttpBinding(),  " ws " );
ep2.Name 
=   " Endpoint2-WSHttp " ;
ep2.Behaviors.Add(
new  MyEndpointBehavior());
Console.WriteLine(
" Opening the host... " );
host.Open();
Console.WriteLine(
" Host opened " );
}
}
}

 

      我并不认为这就是“最优”的添加方法,他只是描述通过特性增加行为的一个特定的例子而已,具体什么是“最优”的添加行为的方法呢?其实这就像软件架构一样,永远没有最好的架构,只有最合适的架构。所以具体项目里面采用哪种方式去添加来得具体情况具体分析。个人比较喜欢用使用配置文件添加的方法….

 

 


 在后面的文章中将会讲诉到具体的行为扩展,敬请期待..

 

        1.1.1. IServiceBehavior
        1.1.2. IContractBehavior
        1.1.3. IEndpointBehavior
        1.1.4. IOperationBehavior

转载于:https://www.cnblogs.com/Creator/archive/2011/05/21/2052687.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值