zoukankan      html  css  js  c++  java
  • 如何通过扩展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(英文)

  • 相关阅读:
    css font-family(字体样式)
    360浏览器兼容模式,页面不能正常渲染
    SVN 如何更换IP地址
    Update 出现在的问题
    安装node-sass
    vue 里面输出带标签的html
    css 内容超出宽度自动换行
    js 判断各种数据类型
    Java_面向对象三大特征
    Java_基础(二)
  • 原文地址:https://www.cnblogs.com/Winston/p/1387260.html
Copyright © 2011-2022 走看看