应用程序使用 Windows Communication Foundation (WCF) 客户端对象调用服务作。 本主题讨论 WCF 客户端对象、WCF 客户端通道及其与基础通道体系结构的关系。 有关 WCF 客户端对象的基本概述,请参阅 WCF 客户端概述。 有关通道层的详细信息,请参阅 扩展通道层。
概述
服务模型运行时将创建由以下内容组成的 WCF 客户端:
服务协定自动生成的客户端实现,它将应用程序代码的调用转换为传出消息,并将响应消息转换为输出参数,并返回应用程序可以检索的值。
控制接口(System.ServiceModel.IClientChannel)的实现,该接口将各种接口组合在一起,并提供对控制功能的访问,尤其是关闭客户端会话并释放通道的能力。
基于所用绑定指定的配置设置生成的客户端通道。
应用程序可以按需创建此类客户端,方法是通过System.ServiceModel.ChannelFactory,或通过创建由 ClientBase<TChannel>生成的派生类的实例。 这些预先生成的客户端类可以封装并委托给由 ChannelFactory 动态构造的客户端通道实现。 因此,生成它们的客户端通道和通道工厂是此讨论的焦点。
客户端对象和客户端通道
WCF 客户端的基本接口是 System.ServiceModel.IClientChannel 接口,它公开核心客户端功能以及基本通信对象功能 System.ServiceModel.ICommunicationObject、上下文功能 System.ServiceModel.IContextChannel以及可扩展行为 System.ServiceModel.IExtensibleObject<T>。
但是,接口 IClientChannel 不定义服务协定本身。 服务协定接口(通常使用 ServiceModel 元数据实用工具工具(Svcutil.exe)之类的工具从服务元数据生成这些声明。 WCF 客户端类型同时扩展 IClientChannel 和目标服务契约接口,使应用程序不仅能够直接调用操作,还可以访问客户端的运行时功能。 创建一个 WCF 客户端可以向 WCFSystem.ServiceModel.ChannelFactory 对象提供必要信息,以便创建可以连接到配置的服务终结点并与此终结点交互的运行时。
如前所述,必须先配置两种 WCF 客户端类型,然后才能使用它们。 最简单的 WCF 客户端类型是派生自 ClientBase<TChannel> 的对象(如果服务协定是双工协定,则派生自 DuplexClientBase<TChannel>)。 可以使用构造函数、以编程方式配置或使用配置文件来创建这些类型,然后直接调用以调用服务作。 要了解ClientBase<TChannel> 对象的基本概述,请参阅 WCF 客户端概述。
第二种类型是在运行时从调用 CreateChannel 方法生成的。 涉及严格控制通信细节的应用程序通常使用此客户端类型(称为 客户端通道对象),因为它可实现比基础客户端运行时和通道系统更直接的交互。
通道工厂
负责创建支持客户端调用的基础运行时的类是 System.ServiceModel.ChannelFactory<TChannel> 类。 WCF 客户端对象和 WCF 客户端通道对象都使用对象 ChannelFactory<TChannel> 来创建实例; ClientBase<TChannel> 派生的客户端对象封装通道工厂的处理,但在许多情况下,直接使用通道工厂是完全合理的。 这种情况的常见情况是,如果要从现有工厂重复创建新的客户端通道。 如果使用客户端对象,可以通过调用 ClientBase<TChannel>.ChannelFactory 属性从 WCF 客户端对象获取基础通道工厂。
要记住的关于通道工厂的重要事项是,他们在调用 ChannelFactory<TChannel>.CreateChannel之前为提供给它们的配置创建新的客户端通道实例。 调用 CreateChannel(或 ClientBase<TChannel>.Open、ClientBase<TChannel>.CreateChannel,或对 WCF 客户端对象执行任何操作)后,就不能修改通道工厂,并期望将通道用于不同的服务实例,即使您只是更改目标终结点地址。 如果要创建具有不同配置的客户端对象或客户端通道,必须先创建新的通道工厂。
有关使用 WCF 客户端对象和 WCF 客户端通道的各种问题的详细信息,请参阅 使用 WCF 客户端访问服务。
以下两个部分介绍了 WCF 客户端通道对象的创建和使用。
创建新的 WCF 客户端通道对象
为了说明客户端通道的使用,假定已生成以下服务协定。
[System.ServiceModel.ServiceContractAttribute(
Namespace = "http://microsoft.wcf.documentation"
)]
public interface ISampleService
{
[System.ServiceModel.OperationContractAttribute(
Action = "http://microsoft.wcf.documentation/ISampleService/SampleMethod",
ReplyAction = "http://microsoft.wcf.documentation/ISampleService/SampleMethodResponse"
)]
[System.ServiceModel.FaultContractAttribute(
typeof(microsoft.wcf.documentation.SampleFault),
Action = "http://microsoft.wcf.documentation/ISampleService/SampleMethodSampleFaultFault"
)]
string SampleMethod(string msg);
}
若要连接到 ISampleService
服务,请直接与通道工厂 (ChannelFactory<TChannel>) 一起使用生成的协定接口。 为特定协定创建和配置通道工厂后,可以调用 CreateChannel 该方法以返回可用于与服务通信的 ISampleService
客户端通道对象。
当 ChannelFactory<TChannel> 类与服务协定接口一起使用时,您必须强制转换到 IClientChannel 接口以显式打开、关闭或中止通道。 为便于操作,Svcutil.exe 工具还生成一个帮助器接口,该接口可同时实现服务协定接口和 IClientChannel ,以使您无需进行强制转换就能够与客户端通道基础结构进行交互。 以下代码显示了实现上述服务协定的帮助程序客户端通道的定义。
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
public interface ISampleServiceChannel : ISampleService, System.ServiceModel.IClientChannel
{
}
创建新的 WCF 客户端通道对象
若要使用客户端通道连接到 ISampleService
服务,请直接通过通道工厂使用生成的协定接口(或帮助程序版本),将协定接口的类型作为类型参数传递。 创建和配置特定协定的通道工厂后,可以调用 ChannelFactory<TChannel>.CreateChannel 该方法以返回可用于与服务通信的 ISampleService
客户端通道对象。
创建后,客户端通道对象实现 IClientChannel 和协定接口。 因此,可以直接使用这些对象来调用操作,与支持该协定的服务进行交互。
使用客户端对象和客户端通道对象之间的区别仅仅在于其易于使用性和开发人员的喜好。 许多熟悉类和对象的开发人员宁愿使用 WCF 客户端对象而不是 WCF 客户端通道。
有关示例,请参阅 How to: Use the ChannelFactory。