第三篇:试着去掉配置文件

通过配置文件来设置Host、Endpoint、Binding等是WCF中推荐的方法,这样可以使发布尽量灵活。其实配置文件中的值,最终还是要体现到代码中的,只不过这部分工作由底层帮你做了。我们今天来尝试去掉配置文件,用纯代码实现发布过程,同时加深一下对层次关系的理解。

1、服务端

在上回的基础上删掉App.config吧,然后把Main方法修改一下:

   
   
   
   
  1. using System;  
  2. using System.ServiceModel;  
  3.   
  4. namespace Server  
  5. {  
  6.     class Program  
  7.     {  
  8.         static void Main(string[] args)  
  9.         {  
  10.             //定义两个基地址,一个用于http,一个用于tcp 
  11.             Uri httpAddress = new Uri("http://localhost:8080/wcf"); 
  12.             Uri tcpAddress = new Uri("net.tcp://localhost:8081/wcf"); 
  13.             //服务类型,注意同样是实现类的而不是契约接口的 
  14.             Type serviceType = typeof(Server.DataProvider); 
  15.  
  16.             //定义一个ServiceHost,与之前相比参数变了 
  17.             using(ServiceHost host = new ServiceHost(serviceType, new Uri[] { httpAddress, tcpAddress }))  
  18.             {  
  19.                 //定义一个basicHttpBinding,地址为空 
  20.                 Binding basicHttpBinding = new BasicHttpBinding(); 
  21.                 string address = ""
  22.                 //用上面定义的binding和address,创建endpoint 
  23.                 host.AddServiceEndpoint(typeof(Server.IData), basicHttpBinding, address); 
  24.  
  25.                 //再来一个netTcpBinding 
  26.                 Binding netTcpBinding = new NetTcpBinding(); 
  27.                 address = ""
  28.                 host.AddServiceEndpoint(typeof(Server.IData), netTcpBinding, address); 
  29.  
  30.                 //开始服务 
  31.                 host.Open();  
  32.                 Console.WriteLine("Service Running ...");  
  33.                 Console.ReadKey();  
  34.                 host.Close();  
  35.             }  
  36.         }  
  37.     }  

如果我们把代码和之前的App.config对比着的地一下,就会发现元素是对应的。我们来整理一下目前为止出现的层级关系:

 ServiceHost
   ├ ServiceType       实现类的类型
   ├ Uri[]                   基地址,对应config中的
   └ ServiceEndpoint[]       服务终结点,对应config中的多个
        ├ ServiceContract    服务契约,对应config中的contract属性
        ├ Binding            绑定,对应config中的binding属性
        └ EndpointAddress    终结点地址,对应config中的address属性


2、客户端

同样可以删掉App.config了,代码改一下:

   
   
   
   
  1. using System;  
  2. using System.ServiceModel;  
  3. using System.ServiceModel.Channels;  
  4.   
  5. namespace Client  
  6. {  
  7.     class Program  
  8.     {  
  9.         static void Main(string[] args)  
  10.         {  
  11.             //定义绑定与服务地址 
  12.             Binding httpBinding = new BasicHttpBinding(); 
  13.             EndpointAddress httpAddr = new EndpointAddress("http://localhost:8080/wcf"); 
  14.             //利用ChannelFactory创建一个IData的代理对象,指定binding与address,而不用配置文件中的  
  15.             var proxy = new ChannelFactory(httpBinding, httpAddr).CreateChannel();  
  16.             //调用SayHello方法并关闭连接 
  17.             Console.WriteLine(proxy.SayHello("WCF"));  
  18.             ((IChannel)proxy).Close();  
  19.  
  20.             //换TCP绑定试试 
  21.             Binding tcpBinding = new NetTcpBinding(); 
  22.             EndpointAddress tcpAddr = new EndpointAddress("net.tcp://localhost:8081/wcf"); 
  23.             var proxy2 = new ChannelFactory(httpBinding, httpAddr).CreateChannel();  
  24.             Console.WriteLine(proxy2.SayHello("WCF"));  
  25.             ((IChannel)proxy2).Close();  
  26.     }  
  27. }  

对照着上面,也来比对一下代码中现出的对象与App.config中的定义:

 ClientEndpoint        客户端终结点,对应config中的
   ├ ServiceContract  服务契约,对应config中的contract属性
   ├ Binding          绑定,对应config中的binding属性
   └ EndpointAddress  地址,对应config中的address属性



一般情况下,还是建议利用App.config来做发布的相关设定,不要写死代码。但如果只能在程序运行时动态获取发布的相关参数,那App.config就不行了。

OK,又前进了一点,下一篇会看看如何传递复杂对象。