十五天精通WCF——第二天 告別煩惱的config配置

一線碼農發表於2015-06-08

 

  經常搞wcf的基友們肯定會知道,當你的應用程式有很多的“服務引用”的時候,是不是有一種瘋狂的感覺。。。從一個環境遷移到另外一個環境,你需要改變的

endpoint會超級tmd的多,簡直就是搞死了人。。。好了,這篇我們來看看如何最小化配置。

 

一:精簡service的config配置

  就像上一篇的程式碼一樣,我的service端的config配置如下:

 1 <?xml version="1.0" encoding="utf-8" ?>
 2 <configuration>
 3 <system.servicemodel>
 4 <behaviors>
 5 <servicebehaviors>
 6 <behavior name="mxbehavior">
 7 <servicemetadata httpgetenabled="true" />
 8 <servicedebug includeexceptiondetailinfaults="true" />
 9 </behavior>
10 </servicebehaviors>
11 </behaviors>
12 <services>
13 <service name="myservice.homeservice" behaviorconfiguration="mxbehavior">
14 <endpoint address="net.tcp://localhost:1920/homeservice" binding="nettcpbinding" contract="myservice.ihomeservice">
15 <identity>
16 <dns value="localhost" />
17 </identity>
18 </endpoint>
19 <endpoint address="mex" binding="mexhttpbinding" contract="imetadataexchange" />
20 <host>
21 <baseaddresses>
22 <add baseaddress="http://localhost:19200/homeservice"/>
23 </baseaddresses>
24 </host>
25 </service>
26 </services>
27 </system.servicemodel>
28 </configuration>

 

  通過上面的程式碼,你應該知道在system.servicemodel下的所有節點都是wcf專屬的節點,所有的節點資料都會被開啟servicehost這個監聽器時捕獲到,下面我可以

通過servicehost這個監聽器的原始碼下面找找相關的讀取config節點的程式碼。

 

 

通過上面的截圖,你是不是有一種感覺,就是service的底層也是通過程式碼動態的讀取config下面的節點來獲取資料,那就意味著我可以直接將程式碼寫入到code中,

對吧,這樣我就可以把我認為該配置的東西配置起來,不該配置的東西全部放到程式碼裡面去,這樣我的靈活性是不是非常的強大。。。。爽吧,說幹就幹。。。

 1     class Program1
 2     {
 3         static void Main(string[] args)
 4         {
 5             ServiceHost host = new ServiceHost(typeof(HomeService), new Uri("http://localhost:19200/HomeService"));
 6 
 7             host.AddServiceEndpoint(typeof(IHomeService), new NetTcpBinding(), "net.tcp://localhost:1920/HomeService");
 8 
 9             //公佈後設資料
10             host.Description.Behaviors.Add(new ServiceMetadataBehavior() { HttpGetEnabled = true });
11             host.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexHttpBinding(), "mex");
12 
13             host.Open();
14 
15             Console.WriteLine("服務已經開啟。。。");
16 
17             Console.Read();
18         }
19     }

 

有人就要說了,地址的話肯定不能是寫死的,必須變活,簡單啊,我就僅僅把ip地址配置到config裡面去不就完事了,對不對。

<configuration>
  <appSettings>
    <add key ="baseurl" value="http://localhost:19200/HomeService"/>
    <add key ="endpoindurl" value="net.tcp://localhost:1920/HomeService"/>
  </appSettings>
 1   class Program1
 2     {
 3         static void Main(string[] args)
 4         {
 5             ServiceHost host = new ServiceHost(typeof(HomeService), new Uri(ConfigurationManager.AppSettings["baseurl"]));
 6 
 7             host.AddServiceEndpoint(typeof(IHomeService), new NetTcpBinding(), ConfigurationManager.AppSettings["endpoindurl"]);
 8 
 9             //公佈後設資料
10             host.Description.Behaviors.Add(new ServiceMetadataBehavior() { HttpGetEnabled = true });
11             host.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexHttpBinding(), "mex");
12 
13             host.Open();
14 
15             Console.WriteLine("服務已經開啟。。。");
16 
17             Console.Read();
18         }
19     }

 

現在看的話,是不是清楚多了,如果你覺得我的程式碼比較累贅,你可以封裝成一個方法,然後就可以動態的配置nettcp,basic,ws*等等對吧。。。好了,說完服

務端,接下來我們看看client端如何避免。

 

二:精簡client的config配置


  就像上一節那樣,如果我用“服務引用”的話,vs會偷偷的用svcutil.exe來給我們生成一個proxy類和一個config檔案,proxy類也就是你看到的xxxclient。。。

可惡的是config裡面會給我生成一些亂七八糟的東西,如下圖:

 1 <?xml version="1.0" encoding="utf-8" ?>
 2 <configuration>
 3 <system.serviceModel>
 4 <bindings>
 5 <netTcpBinding>
 6 <binding name="NetTcpBinding_IHomeService" />
 7 </netTcpBinding>
 8 </bindings>
 9 <client>
10 <endpoint address="net.tcp://localhost:1920/HomeService" binding="netTcpBinding"
11 bindingConfiguration="NetTcpBinding_IHomeService" contract="HomeServiceReference.IHomeService"
12 name="NetTcpBinding_IHomeService">
13 <identity>
14 <dns value="localhost" />
15 </identity>
16 </endpoint>
17 </client>
18 </system.serviceModel>
19 </configuration>

 

同伺服器端一樣,如果我用code做掉,是不是非常的爽呢???那可不可以做掉呢? 我們還得看一下proxy的原始碼,首先你會看到其實所謂的proxy只是一個繼承

自clientbase的一個類,如下圖。

 

 

上面的兩幅圖,你會發現,最後的proxy類是通過ChannelFactory<TChannel>類來完成助攻的,那話說回來了,既然底層用了ChannelFactory<TChannel>,

那何不我在程式碼裡面就用ChannelFactory<TChannel>不是更好嗎???這樣config也省了,對吧,說幹就幹啦。。。

1     static void Main(string[] args)
2         {
3             ChannelFactory<IHomeService> factory = new ChannelFactory<IHomeService>(new NetTcpBinding(), "net.tcp://localhost:1920/homeservice");
4 
5             var channel = factory.CreateChannel();
6 
7             var result = channel.GetLength("12345");
8         }

 

好了,程式碼就這麼簡單,現在是不是感覺自己萌萌大啦~~~

 

相關文章