老老实实学WCF
第五篇 再探通信--ClientBase
在上一篇中,我们抛开了服务引用和元数据交换,在客户端中手动添加了元数据代码,并利用通道工厂ChannelFactory<>类创建了通道,实现了和服务端的通信。然而,与服务端通信的编程模型不只一种,今天我们来学习利用另外一个服务类ClientBase<>来完成同样的工作,了解了这个类的使用方法,我们对服务引用中的关键部分就能够理解了。
ClientBase<>类也是一个泛型类,接受服务协定作为泛型参数,与ChannelFactory<>不同的是,这个类是一个基类,即抽象类,是不能实例化成对象直接使用的,我们需要自己写一个类来继承这个类,我们新写的类实例化出来就是客户端代理了,这个对象可以调用基类的一些受保护的方法来实现通信。ClientBase<>为我们封装的很好,我们只需要写个新类来继承他就可以了,通信的很多部分他都替我们做好了,比如我们不用进行去创建通道和打开通道的操作,直接调用协定方法就可以了。这也是服务引用和其他元数据生成工具(如svcutil)使用这个类来构造客户端代理的原因。
我们一边动手一边学习
1. 建立客户端程序
我们依然不用服务引用,完全手写,这次还是建立一个控制台应用程序作为客户端。
2. 添加必要的引用
我们用到的ClientBase<>类在System.ServiceModel程序集中,因此,要添加这个程序集的引用,同时在program.cs中添加using语句
using System.ServiceModel;
这一步应该很熟了,如果有疑问,返回前几篇温习一下。
3. 编写服务协定
因为没有使用服务引用,客户端现在没有任何元数据的信息,我们要来手写。首先把服务协定写进去。这个再熟悉不过了(写在Program类后面):
[ServiceContract] public interface IHelloWCF { [OperationContract] string HelloWCF(); }
4. 编写客户端代理类
上面已经提到,我们要自己写一个新类来继承ClientBase<>基类,这样这个新类就是代理类了,同时,为了能够用代理类直接调用服务协定的方法,我们还要让代理类实现服务协定的接口,注意,继承要写在前面,实现接口要写在后面。我们把这个类起名为HelloWCFClient。
public class HelloWCFClient : ClientBase<IHelloWCF>, IHelloWCF { }
提供给ClientBase的泛型参数应该是服务协定,这样他才能帮我们建立正确的通道,同时,代理类也实现服务协定接口。
ClientBase<>有许多的构造函数,接受不同种类的参数来创建代理类对象,其实这些参数都是元数据信息,刚才我们已经通过泛型参数传递给基类服务协定这个元数据了,现在基类还需要绑定和终结点地址这两个元数据才能正确创建连接,所