WCF体系架构
本章内容全面地介绍了建立和使用简单的WCF服务所需要的知识。然而,正如本书其余章节将要描述的那样,WCF提供了对可靠性、事务性、并发管理、安全性以及实例激活等技术的有力支持,它们均依赖于基于拦截机制的WCF体系架构(WCF Architecture)。通过代理与客户端的交互意味着WCF总是处于服务与客户端之间,拦截所有的调用,执行调用前和调用后的处理。当代理将调用栈帧(Stack Frame)序列化到消息中,并将消息通过通道链向下传递时,WCF就开始执行拦截。通道相当于一个拦截器,目的在于执行一个特定的任务。每个客户端通道都会执行消息的调用前处理。链的组成与结构主要依赖于绑定。例如,一个通道对消息编码(二进制格式、文本格式或者MTOM),另一个通道传递安全的调用上下文;还有一个通道传播客户端的事务,一个通道管理可靠会话,另一个通道对消息正文(Message Body)加密(如果进行了配置),诸如此类。客户端的最后一个通道是传输通道,根据配置的传输方式发送消息给宿主。
在宿主端,消息同样通过通道链进行传输,它会对消息执行宿主端的调用前处理。宿主端的第一个通道是传输通道,接收传输过来的消息。随后的通道执行不同的任务,例如消息正文的解密、消息的解码、参与传播事务、设置安全准则、管理会话、激活服务实例。宿主端的最后一个通道负责将消息传递给分发器(Dispatcher)。分发器将消息转换到一个栈帧,并调用服务实例。执行顺序如图1-11所示。

图1-11:WCF体系架构
服务并不知道它是否被本地客户端调用。事实上,服务会被本地客户端 —— 分发器调用。客户端与服务端的拦截器确保了它们能够获得运行时环境,以便于它们执行正确的操作。服务实例会执行调用,然后将控制权(Control)返回给分发器。分发器负责将返回值以及错误信息(如果存在)转换为一条返回消息。分发器获得控制权,执行的过程则刚好相反:分发器通过宿主端通道传递消息,执行调用后的处理,例如管理事务、停用实例、回复消息的编码与加密等。为了执行客户端调用后的处理,包括解密、解码、提交或取消事务等任务,传输通道会将返回消息发送到客户端通道。最后一个通道将消息传递给代理。代理将返回消息转化到栈帧,然后将控制权返回给客户端。
特别值得注意的是,体系架构中的所有要点均与可扩展性息息相关。我们可以为专有交互定制通道,为实例管理定制行为,以及定制安全行为等。事实上,WCF提供的标准功能都能够通过相同的可扩展模式实现。本书介绍了许多针对可扩展性的实例与应用。
宿主体系架构
如何将与技术无关的面向服务交互转换为CLR接口与类,对这一技术的探索无疑充满了趣味。宿主消除了两者之间的鸿沟,搭建了相互之间转换的桥梁。每个.NET宿主进程都包含了多个应用程序域。每个应用程序域则包含了零到多个宿主实例。每个服务宿主实例专门对应于一个特殊的服务类型。创建一个宿主实例,实际上就是为对应于基地址的宿主机器的类型,注册一个包含了所有的终结点的服务宿主实例。每个服务宿主实例拥有零到多个上下文(Context)。上下文是服务实例最核心的执行范围。一个上下文最多只能与一个服务实例关联,这意味着上下文可能为空,不包含任何服务实例。体系架构如图1-12所示。

图1-12:WCF宿主体系架构
注意:WCF上下文的概念与企业服务上下文(Enterprise Services Context)或者.NET上下文绑定对象(Context-Bound Object)的上下文概念相似。
WCF上下文将服务宿主与公开本地CLR类型为服务的上下文组合在一起。当消息经由通道进行传递时,宿主会将消息映射到新的或者已有的上下文(内部包含对象实例),然后通过上下文处理调用。





