如何通过扩展WCF来定制和扩展WCF行为
2013-05-02 01:43
495 查看
转自: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种方式: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.配置告知 1. 定义一个extension(需要指定extension name和extension 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:
客户端:
服务端:
参考网站: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种方式: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.配置告知 1. 定义一个extension(需要指定extension name和extension 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相关文章推荐
- 如何通过扩展WCF来定制和扩展WCF行为
- 通过WCF Extension定制扩展WCF行为
- 通过WCF Extension定制扩展WCF行为
- 通过“四大行为”对WCF的扩展[实例篇]
- 利用定制行为扩展WCF之-利用MessageInsepctor behaviourExtension扩展WCF行为(自定义消息头)
- 通过MessageInsepctor扩展WCF行为-自定义消息头
- 通过“四大行为”对WCF的扩展[原理篇]
- 通过“四大行为”对WCF的扩展[实例篇]
- 通过“四大行为”对WCF的扩展[原理篇]
- 通过“四大行为”对WCF的扩展[原理篇]
- 通过“四大行为”对WCF的扩展[实例篇]
- 通过定制行为拦截WCF消息
- 通过自定义ServiceHost实现对WCF的扩展[实例篇]
- Web项目或WCF发布IIS后,如何通过VS2010调试
- WCF技术剖析之二十六:如何导出WCF服务的元数据(Metadata)[扩展篇]
- 如何通过活动目录(ADSI)修改IIS6中的 Web 服务扩展
- 扩展WCF行为,自定义消息头,实现客户端标识的传递
- WSS3SDK之:如何通过重定向来定制Mobile主页
- 扩展系统Contacts menu后,通过点击这个Menu item如何获取被highlight contact的电话号码???????????
- 如何通过3/8译码器扩展处理器片选信号 推荐