《WCF技术内幕》翻译18:第1部分_第4章_WCF101:从外部剖析WCF2011-06-08 博客园 Frank Xu Lei译尽管WCF是一个相当复杂的平台,但对于偶然的一个学习者来说它看起来还是 相当简单的。正如你在Hello WC例子里看到的一样,构建一个接受程序可以简化 为使用地址、绑定和契约配置一个或者多个终结点。构建一个发送程序可以简单 理解为使用一个地址、绑定和契约向接收终结点发送消息。如果我们要修改发送 者或者接收者的处理过程,我们可以随便这么做,使用我们自己的行为配置或者 使用WCF的自带行为(比如增加元数据支持)。图4-1展示了Endpoints、 addresses、bindings、contracts和behaviors之间的关系。

图4-1:Endpoints、 addresses、bindings、contracts和behaviors地址所有发送或者接收消息的程序必须在终结点上使用某个地址。例如,接收程 序在某个地址上侦听请求消息,而发送程序发送消息到目标地址。WCF 接收基础 结构依赖System.Uri类型去构建接收终结点。WCF发送基础结构,换句话说,依 赖 System.ServiceModel.EndpointAddress类型发送消息给最终接收者。 System.ServiceModel.EndpointAddress类型是对WS-Addressing 中终结点参考 规范的CLR抽象,发送者使用这个类型去为请求消息添加终结点信息,并与接收 终结点建立连接(如果存在接收终结点)第5章包含了EndpointAddress类型的详 细介绍。在WCF里,地址在某些形式上,是一个URI(EndpointAddress对象包装了一个 System.Uri对象)。一个关键部分就是URI里的scheme名。Scheme是URI表示的标 识符的抽象,scheme名是一种标识scheme的方式。在许多情况下,scheme名匹配 可以定位资源的协议,因此使用URI作为URL。例如,URI http://localhost:5000/IHelloWCF标识http为scheme名,并且如此偶然的是 http(超文本传输协议)也是一个传输模式。在内部看,WCF基础结构必须能够使 用URInate去构建发送或者接收基础结构。绑定绑定是我们表示消息应用如何处理、发送和接收消息的主要方式。更确切地 说,它表示传输、WS-*协议、安全需求、事务需求和终结点的主要方式。WCF包 含9种覆盖传输、WS-*协议、安全需求、事务需求的绑定。如果这些绑定不能满 足我们的需求,我们还可以定义符合我们特定需求的绑定。通常来说,绑定是定义消息基础结构的一个类型;它是我们程序支持传输和 协议的一个抽象层。对于开发人员,这个抽象意味着通过TCP/IP传输发送消息的 代码和通过MSMQ发送消息的代码看起来非常相似,因此把我们的程序从特定的传 输或者协议里解耦。此种方式的松耦合意味着开发人员可以开发、改变和定制一 个应用比以前更快地满足客户要求。所有的绑定类型都是System.ServiceModel.Channels.Binding的子类型,于 是它们都有相同的属性。一个共同的属性就是他们维护者一个私有 System.ServiceModel.Channels.BindingElement对象的列表。一个 BindingElement 是消息交换一个特定方面的抽象,像传输或者WS-*协议。所有 的绑定暴露了一个名为CreateBindingElements的方法,这个方法可以构建和返 回特定绑定元素的列表。下面展示的是一个简单程序,它包含WCF里的9种绑定, 并迭代显示它们的BindingElement列表:
using System;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.Reflection;
using System.Collections.Generic;
using System.ServiceModel.MsmqIntegration;
sealed class BindingElementsShow
{
static void Main(){
List<Binding> bindings = new List<Binding> ();
bindings.Add(new BasicHttpBinding());
bindings.Add(new NetNamedPipeBinding());
bindings.Add(new NetTcpBinding());
bindings.Add(new WSDualHttpBinding());
bindings.Add(new WSHttpBinding());
bindings.Add(new NetMsmqBinding());
bindings.Add(new MsmqIntegrationBinding());
bindings.Add(new WSFederationHttpBinding());
// throws if Peer Networking not installed
bindings.Add(new NetPeerTcpBinding());
ShowBindingElements(bindings);
}
private static void ShowBindingElements(List<Binding> bindings){
foreach (Binding binding in bindings){
Console.WriteLine("Showing Binding Elements for {0}",
binding.GetType().Name);
foreach (BindingElement element in binding.CreateBindingElements()){
Console.WriteLine(" {0}", element.GetType ().Name);
}
}
}
}