WCF客户端和服务端的框架体系相互协作,使得开发人员可以按照我们熟悉的方式进行异常的处理:在服务操作执行过程中抛出异常(FaultException),在调用服务时捕获异常,完全感觉不到“分布式”的存在,如同典型的“本地”操作一般。为了实现这样的效果,WCF在内部为我们作了很多。

消息交换是WCF进行通信的唯一手段,消息不仅仅是正常服务调用请求和回复的载体,服务端抛出的异常,甚至是服务的元数据都是通过消息的形式传向客户端的。所以,实现异常与消息之间的转换是整个异常处理体系的核心,而WCF的异常处理框架就着力于完成这样的功能。

WCF技术剖析之二十二: 深入剖析WCF底层异常处理框架实现原理[下篇]我们可以这样来简单地描述WCF异常处理框架的功能实现:WCF服务端将抛出的FaultException异常进行序列化,并根绝消息的SOAP规范(SOAP 1.1或SOAP 1.2)和WS-Addressing规范(WS-Addressing 2004和WS-Addressing 1.0)生成Fault消息。被传入信道层,经过一系列的信道后,该Fault消息最终借助于传输层返回到客户端;客户端信道层接收到该Fault消息并经过相应的处理后,被反序列化。反序列化的结果即实现对FaultException的重建,WCF最终将重建的FaultException异常抛出,对于最终的开发者而言,感觉就像服务端抛出的FaultException直接被客户端捕获了一样。在上面的内容中我们说过:WCF并不直接进行FaultException和Fault消息之间的转换,而是借助于MessageFault这一中间对象。右图体现了错误(Fault)在整个WCF异常处理过程中的流转。

通过中篇的介绍,我们知道:对FaultException进行序列化和反序列化的核心对象是FaultFormatter,了解WCF整个异常处理框架的实现原理首先需要知道FaultFormatter是如何创建的。

一、FaultFormatter是如何创建的?

WCF的服务端和客户端均需要一个FaultFormatter对象,分别用于对FaultException异常对象的序列化和反序列化,现在我们分别介绍FaultFormatter对象在服务端和客户端是如何被创建的。

1、FaultFormatter(DispatchFaultFormatter)在服务端如何被创建

FaultFormatter在服务端创建于服务寄宿之时。具体来讲,在ServiceHost被初始化过程中,WCF会为服务的每个终结点创建相应的终结点分发器(EndpointDispatcher)。而对于每一个被创建出来的终结点分发器都具有一个相应的分发运行时(DispatchRuntime)。DispatchRuntime是整个WCF运行时框架的核心,一系列的对象和组件被它引用以实现对整个消息分发和操作执行行为的控制。(关于整个服务寄宿在WCF服务端框架内的执行流程,在《WCF技术剖析(卷1)》的第7章有详细的介绍。)

DispatchRuntime的初始化过程中,WCF会根据服务的描述创建一系列的DispatchOperation对象。DispatchOperation对象可以看成是某个服务操作在运行时的表示,最终对服务操作的执行就是通过它来完成的。具体来讲,WCF会获取当前终结点的契约描述(ContractDescription),遍历每一个操作描述(OperationDescription)借此创建相应的DispatchOperationServiceEndpointContractDescriptionOperationDescription三者之间的关系通过下面的类型定义代码一目了然。

class ServiceEndpoint
   2: {
//其他成员
public ContractDescription Contract { get; }
   5: }
class ContractDescription
   7: {
//其他成员
public OperationDescriptionCollection Operations { get; }
  10: }
class OperationDescription
  12: {
//其他成员
public FaultDescriptionCollection Faults { get; }
  15: }

相关文章: