zoukankan      html  css  js  c++  java
  • 如何通过扩展WCF来定制和扩展WCF行为

    转自:http://www.cnblogs.com/Winston/archive/2009/02/10/1387260.html

    参考网站:http://msdn.microsoft.com/zh-cn/magazine/cc163302.aspx  

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

    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:

    客户端:

     

     

     

    服务端:

     

     

     

    Carlos Figueira MSDN blog

    http://blogs.msdn.com/b/carlosfigueira/archive/2011/03/14/wcf-extensibility.aspx

  • 相关阅读:
    精准医疗
    生物信息学的研究过程
    蛋白质结构预测
    CP
    基因组大小控制因素
    RNA组研究困难
    输入input文本框的 U+202D和U+202C是什么
    ruby-get-url-query-params
    golang send post request
    nginx location配置
  • 原文地址:https://www.cnblogs.com/younggun/p/3053956.html
Copyright © 2011-2022 走看看