您的位置:首页 > 其它

如何通过扩展WCF来定制和扩展WCF行为

2009-02-10 11:10 393 查看
当我们需要扩展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:

客户端:



服务端:



有关Extending WCF with custom behaviors的详细文档,请参阅:

http://msdn.microsoft.com/zh-cn/magazine/cc163302.aspx(中文)

http://msdn.microsoft.com/en-us/magazine/cc163302.aspx(英文)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: