挽星

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

转自: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

posted on 2013-05-02 01:43  挽星  阅读(292)  评论(0编辑  收藏  举报