好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

通过WCF Extension定制扩展WCF行为

通过WCF Extension定制扩展WCF行为

通过WCF Extension定制扩展WCF行为

功能介绍

当我们需要扩展WCF的功能,或者需要实现某些特定的功能,我们必须应用WCF的扩展定制功能(WCF extension),WCF framework提供了丰富的可扩展性,其提供的可扩展接口如下所示:

WCF定制行为相关的namespace主要包括2个:

System.ServiceModel.Disptcher: 该namespace主要用来用来定制行为,他们可以用来扩展WCF的服务模型。 System.ServiceModel.Channels: 该namespace用来定义定制绑定元素,它们可以扩展WCF的信道层。

实现定制行为的步骤 实现定制行为一般分为3步:

1. 声明扩展: 声明所要提供的行为的类型, 例如是工作在客户端中以将发送的数据序列化到消息里,还是工作在服务中以管理服务类型的实例等等。

2. 附加扩展: 第2步需要将所定制的extension附加到相应的操作,终结点或者服务端行为上。

例如对于客户端来说: 当他是操作相关(Operation)的时候,则将该定制行为附加到操作上,即实现System.ServiceModel.Description.IOperationBehavior接口。 当他是终结点(Endppoint)相关的时候 ,则将该定制行为附加到终结点上,即实现System.ServiceModel.Description.IEndpointBehavior接口。

3. 告知(inform): 告知的作用就是将那些自己定义的扩展行为告知客户端运行时组件(ClientRunTime)或者服务端调度器(EndpointDispatcher)。

对于附加到操作上的扩展行为,只能采用programatically的方式告知,而对于附加到终结点上的扩张行为,告知的方式有2种,分别为programatically和administratively:

使用代码告知(programmatically)

以客户端为例: 当把该定制行为附加到operation上时,即实现了IOperationBehavior时候,其告知行为应该为operation-level的:

 public   MyServiceClient()
    {
           foreach  (System.ServiceModel.Description.OperationDescription operation  in   base  .Endpoint.Contract.Operations)
            {
                operation.Behaviors.Add(  new   MyParameterInspector());
            }
      
        //    base.Endpoint.Contract.Operations[0].Behaviors.Add(new WCFClient.MyParameterInspector()); 
    }

当把该定制行为 附加到endpoint上时,其告知行为应该为endpoint-level的。

  public   MyServiceClient()
    {
         base .Endpoint.Behaviors.Add( new   MyMessageInspector());
    } 

使用配置告知(administratively)

为了通过配置告知WCF服务模型定制行为的存在,必须提供一个从抽象基类System.ServiceModel.Configuration.BehaviorExtensionElement继承的类。

实例讲解

实例1. 定制一个客户端消息检查器来扩展客户端Endpoint的行为

声明:通过实现System.ServiceModel.Disptcher.IClientMessageInspector接口来声明一个消息检查的扩展行为

 public   class   MyMessageInspector : System.ServiceModel.Dispatcher.IClientMessageInspector
    {
          #region  IClientMessageInspector implementation
         public   void   AfterReceiveReply(
              ref   System.ServiceModel.Channels.Message reply,
              object   correlationState)
        {
            Console.WriteLine(  "  --------------------  "  );
            Console.WriteLine(  "  AfterReceiveReply Behavior extension  "  );
            Console.WriteLine(  "  --------------------  "  );
        }
 
          public   object   BeforeSendRequest(
              ref   System.ServiceModel.Channels.Message request,
            System.ServiceModel.IClientChannel channel)
        {
            Console.WriteLine(  "  --------------------  "  );
            Console.WriteLine(  "  Before Sending Request Behavior extension  "  );
            Console.WriteLine(  "  --------------------  "  );
              return   null  ;
        }
          #endregion   
 
 
    } 

附加: 通过实现 System.ServiceModel.Discription.IEndpointBehavior 接口来完成该扩张行为在客户段的附加

 public   class   MyMessageInspector : System.ServiceModel.Dispatcher.IClientMessageInspector,
        System.ServiceModel.Description.IEndpointBehavior
{
  //  声明部分: 
         #region  IClientMessageInspector implementation
         public   void   AfterReceiveReply(
              ref   System.ServiceModel.Channels.Message reply,
              object   correlationState)
        {
        }
 
          public   object   BeforeSendRequest(
              ref   System.ServiceModel.Channels.Message request,
            System.ServiceModel.IClientChannel channel)
        {
              return   null  ;
        }
          #endregion  
 
 //  附加部分: 
         #region  Implementation for IEndpointBehaviour
         public   void   AddBindingParameters(ServiceEndpoint serviceendpoint,
            BindingParameterCollection parameters
            )
        {
              //  no implementation; 
         }
 
          public   void   ApplyClientBehavior(
            ServiceEndpoint serviceendpint,
            ClientRuntime behavior)
        {
            behavior.MessageInspectors.Add(  this  );
        }
 
          public   void   ApplyDispatchBehavior(
            ServiceEndpoint serviceendpoint,
            EndpointDispatcher dispatcher)
        {
 
        }
 
          public   void   Validate(ServiceEndpoint serviceendpoint)
        {
              //  no implemetentation; 
         }
          #endregion   
    } 

告知:告知WCF服务模型该行为的存在,有2种方式:programmatically和administratively. 为了实现服务与配置的低耦合,administratively是推荐的方式。

注意:通过培植方式将定制行为告知 WCF,必须提供一个从抽象基类System.ServiceModel.Configuration.BehaviorExtensionElement继承的类。

1. 重写基类

 public   class   MyBehaviorExtensionelement : System.ServiceModel.Configuration.BehaviorExtensionElement
    {
 
          public   override   Type BehaviorType
        {
              get  {  return   typeof  (MyMessageInspector); }
        }
 
          protected   override   object   CreateBehavior()
        {
              return   new   MyMessageInspector();
        }
} 

2. 配置告知  

定义一个extension(需要指定extension name和extension type)

选定刚才的 extension

将该 extension 应用到 EndpointBehavior

实例2. 定制一个服务端错误处理器来扩展服务端错误处理机制

扩展行为声明和附加

 public   class   MyErrorHandler : IErrorHandler,IServiceBehavior
{
  //  声明扩展部分 
         public   bool   HandleError(Exception error)
        {
            Console.WriteLine(  "  The exception information will be logged:  "  );
            Console.WriteLine(error.Message);
              return   true  ;
        }
 
          public   void  ProvideFault(Exception error, MessageVersion version,  ref   Message fault)
        {
           
        }
  //  附加扩展部分 
         #region  Implementation for IServiceBehaviour
         public   void   AddBindingParameters(ServiceDescription descip,
            ServiceHostBase host,
            Collection <ServiceEndpoint>  endpoints,
            BindingParameterCollection parameters
            )
        {
              //  no implementation; 
         }
 
          public   void   ApplyDispatchBehavior(ServiceDescription desciption,
            ServiceHostBase host)
        {
            IErrorHandler hanlder  =  new   MyErrorHandler();
              foreach  (ChannelDispatcher dispatcher  in   host.ChannelDispatchers)
            {
                dispatcher.ErrorHandlers.Add(hanlder);
            }
        }
 
          public   void   Validate(ServiceDescription description,
            ServiceHostBase host)
       {
              //  no implemetentation; 
         }
          #endregion   
 
    } 

  告知

 public   class   MyErrorBehaviorExtensionElement : System.ServiceModel.Configuration.BehaviorExtensionElement
{
          public   override   Type BehaviorType
        {
              get  {  return   typeof  (MyErrorHandler); }
        }
          protected   override   object   CreateBehavior()
        {
              return   new   MyErrorHandler();
        }
} 

客户端consume WCF service snippet:

 namespace   WCFClient
{
      class   Program
    {
          public   class   ClientWrapper:IDisposable
        {
              private   MyServiceClient _proxy;
              public   ClientWrapper()
            {
                _proxy  =  new   MyServiceClient();
            }
 
              public   void  MyMethod( bool   ThrowExporNot)
            {
                  try  
                {
                    _proxy.MyMethod(ThrowExporNot);
                }
                  catch  (System.ServiceModel.FaultException<MyCustomException>  ex)
                {
                    Console.WriteLine(ex.Reason);
                   
                }
            }
 
              public   void   Dispose()
            {
                _proxy.Close();
            }
            
        }
 
          static   void  Main( string  [] args)
        {
            ClientWrapper wrap  =  new   ClientWrapper();
            wrap.MyMethod(  true  );          
            Console.Read();
        }
            
    }
} 

服务端self-hosted WCF service snippet:

 class   Program
    {
          static   void  Main( string  [] args)
        {
            ServiceHost host  =  new  ServiceHost( typeof  (MyService));
          
            Console.WriteLine(  "  The service is online...  "  );
            Console.WriteLine(  "  Press <ENTER> to exit  "  );
            host.Open();
            Console.Read();
        }
} 

运行结果

客户端:

服务端:

参考文档

更多Extending WCF with custom behaviors的详细文档,请参阅:

http://msdn.microsoft.com/zh-cn/magazine/cc163302.aspx (中文)

http://msdn.microsoft.com/en-us/magazine/cc163302.aspx (英文)




希望以上文章对您有所帮助

Winston

 

 

分类:  技术分享 - WCF

标签:  WCF Extension

作者: Leo_wl

    

出处: http://www.cnblogs.com/Leo_wl/

    

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

版权信息

查看更多关于通过WCF Extension定制扩展WCF行为的详细内容...

  阅读:52次