通过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行为的详细内容...