WCF网络客户端的三种实现方式

    在.net程序设计中,由于引入了类型元数据信息,所以我们可以在程序设计中利用反射机制得到强类的使用.从而避免运行时的类型错误.不过在跨应用程序域的程序设计中我们由于也要使用强类型:一种方式是完全引用源程序集,不过随之而来的问题是程序集的成倍膨涨,因此这种方式在实际应用中是没有多大的优势的,几乎不可以作为开发级使用.第二种方式是利用类型工具如.net下的soapsuds.exe工具来得到类型元数据。不过在跨应用程序设计中我们一般利用接口来解藕这种类型设计。

   在WCF中提供四种方式来实现客户端的类型元数据信息的获取:

   一、利用工具svcutil.exe命令行来得到代理类型。

         svcutil.exe {终结点}/out:{输出文件.cs}/config:{配置文件.config}

         如:  svcutil.exe http://localhost:8000/Derivate/ /out:Client.cs /config:app.config

   二、利用工厂类ChannelFactory<T>来实现。它将生成一个代理变量。如我们有一个服务契约:IService那么我们就可以按如下的方式来得到代理类:

         ChannelFactory<IService>  factory=new ChannelFactory<IService>(“BasicHttpBinding_IService”);//以配置信息为参数的工厂类

         IService proxy=factory.CreateChannel();//得到代理类实例。

        现在就可以使用IService接口的方法了。

   三、继承一个来自ClientBase<T>或DuplexClientBase<T>,后者是要实现客户回调时的基类。

        例如我们这儿的接口IService有一个方法void AddService(string service),我们可以这样得到一个代理类。

        public class ServiceProxy:ClientBase<IService>,IService

        {

             //这儿可以实现IService的方法。

             void AddService(string service)

             {

                 base.Channel.AddService(service);//由信道对象得到方法的调用。

             }

         }

    四、最后一种方法是使用WCF的MetadataExchangeClient类来得到类型元数据信息。这个类是在System.ServiceModel.Description名字空间下。先来看看这个方法的一些重要的方法

        MetadataSet GetMetadata();//得到类型元数据集

        ServiceEndpointCollection ImporterAllEndpoint();//WsdlImporter类的方法得到所有的终结点。

   现在我们来看如何使用这个类:

    

由自己下载的元数据信息创建客户端

MetadataExchangeClient metadataExchangeClient = new MetadataExchangeClient(
                       new Uri("
http://localhost:8000/IService/?wsdl"), MetadataExchangeClientMode.HttpGet);
MetadataSet metadataSet = metadataExchangeClient.GetMetadata();//从服务器端下载元数据
WsdlImporter importer = new WsdlImporter(metadataSet);//得到一个导入器
ServiceEndpointCollection endpoints = importer.ImportAllEndpoints();//导入所有的终结点
List<IService> proxies = new List<IService>();
foreach (var endpoint in endpoints)
{
    proxies.Add ( new ChannelFactory<IService>(

                         endpoint.Binding, endpoint.Address).CreateChannel());//由得到的终结点信息创建客户端代理
}

posted @ 2010-03-27 22:21  suyan010203  Views(790)  Comments(0Edit  收藏  举报