如何通过扩展WCF来定制和扩展WCF行为

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

1.       WCF定制行为相关的namespace
用来扩展WCF扩展行为的namespace主要包括2个:
a. System.ServiceModel.Disptcher:
namespace主要用来用来定制行为,他们可以用来扩展WCF的服务模型。
b. System.ServiceModel.Channels:
namespace用来定义定制绑定元素,它们可以扩展WCF的信道层。

2.       定制行为的分类

3.       实现定制行为的步骤
实现定制行为一般分为3步:
1. 声明扩展:
     声明所要提供的行为的类型, 例如是工作在客户端中以将发送的数据序列化到消息里,还是工作在服务中以管理服务类型的实例等等
2.附加扩展:
    2步需要将所定制的extension附加到相应的操作,终结点或者服务端行为上。
例如对于客户端来说:

a.       当他是操作相关(Operation)的时候,则将该定制行为附加到操作上,即实现System.ServiceModel.Description.IOperationBehavior接口。

b.      当他是终结点(Endppoint)相关的时候 ,则将该定制行为附加到终结点上,即实现System.ServiceModel.Description.IEndpointBehavior接口。

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

对于附加到操作上的扩展行为,只能采用programatically的方式告知,而对于附加到终结点上的扩张行为,告知的方式有2种,分别为programatically和administratively:
     a.  使用代码告知(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());
    }

 

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

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

step1: 声明

通过实现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

 

 

    }

step2:
附加

通过实现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

    }

 

Step3: 告知(inform)

告知WCF服务模型该行为的存在,有2种方式:programmaticallyadministratively. 为了实现服务与配置的低耦合,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.配置告知
 1.
定义一个extension(需要指定extension nameextension type)


 

2. 选定刚才的extension

 

3.       将该extension应用到EndpointBehavior

 

 

 

 

实例讲解2-定制一个服务端错误处理器来扩展服务端错误处理机制
 1 扩展行为声明和附加


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

 

    }

 2. 告知
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();

        }

}

运行结果screenshot:

客户端:

 

 

服务端:

 

 

 

有关Extending WCF with custom behaviors的详细文档,请参阅:

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

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

原文地址:https://www.cnblogs.com/Winston/p/1387260.html