經常搞wcf的基友們肯定會知道,當你的應用程序有很多的“服務引用”的時候,是不是有一種瘋狂的感覺。。。從一個環境遷移到另外一個環境,你需要改變的
endpoint會超級tmd的多,簡直就是搞死了人。。。好了,這篇我們來看看如何最小化配置。
## 一:精簡service的config配置
就像上一篇的代碼一樣,我的service端的config配置如下:
~~~
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.servicemodel>
<behaviors>
<servicebehaviors>
<behavior name="mxbehavior">
<servicemetadata httpgetenabled="true" />
<servicedebug includeexceptiondetailinfaults="true" />
</behavior>
</servicebehaviors>
</behaviors>
<services>
<service name="myservice.homeservice" behaviorconfiguration="mxbehavior">
<endpoint address="net.tcp://localhost:1920/homeservice" binding="nettcpbinding" contract="myservice.ihomeservice">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexhttpbinding" contract="imetadataexchange" />
<host>
<baseaddresses>
<add baseaddress="http://localhost:19200/homeservice"/>
</baseaddresses>
</host>
</service>
</services>
</system.servicemodel>
</configuration>
~~~
通過上面的代碼,你應該知道在system.servicemodel下的所有節點都是wcf專屬的節點,所有的節點數據都會被開啟servicehost這個監聽器時捕獲到,下面我可以
通過servicehost這個監聽器的源碼下面找找相關的讀取config節點的代碼。
?
通過上面的截圖,你是不是有一種感覺,就是service的底層也是通過代碼動態的讀取config下面的節點來獲取數據,那就意味著我可以直接將代碼寫入到code中,
對吧,這樣我就可以把我認為該配置的東西配置起來,不該配置的東西全部放到代碼里面去,這樣我的靈活性是不是非常的強大。。。。爽吧,說干就干。。。
~~~
class Program1
{
static void Main(string[] args)
{
ServiceHost host = new ServiceHost(typeof(HomeService), new Uri("http://localhost:19200/HomeService"));
host.AddServiceEndpoint(typeof(IHomeService), new NetTcpBinding(), "net.tcp://localhost:1920/HomeService");
//公布元數據
host.Description.Behaviors.Add(new ServiceMetadataBehavior() { HttpGetEnabled = true });
host.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexHttpBinding(), "mex");
host.Open();
Console.WriteLine("服務已經開啟。。。");
Console.Read();
}
}
~~~
有人就要說了,地址的話肯定不能是寫死的,必須變活,簡單啊,我就僅僅把ip地址配置到config里面去不就完事了,對不對。
~~~
<configuration>
<appSettings>
<add key ="baseurl" value="http://localhost:19200/HomeService"/>
<add key ="endpoindurl" value="net.tcp://localhost:1920/HomeService"/>
</appSettings>
~~~
~~~
class Program1
{
static void Main(string[] args)
{
ServiceHost host = new ServiceHost(typeof(HomeService), new Uri(ConfigurationManager.AppSettings["baseurl"]));
host.AddServiceEndpoint(typeof(IHomeService), new NetTcpBinding(), ConfigurationManager.AppSettings["endpoindurl"]);
//公布元數據
host.Description.Behaviors.Add(new ServiceMetadataBehavior() { HttpGetEnabled = true });
host.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexHttpBinding(), "mex");
host.Open();
Console.WriteLine("服務已經開啟。。。");
Console.Read();
}
}
~~~
現在看的話,是不是清楚多了,如果你覺得我的代碼比較累贅,你可以封裝成一個方法,然后就可以動態的配置nettcp,basic,ws*等等對吧。。。好了,說完服
務端,接下來我們看看client端如何避免。
## 二:精簡client的config配置
就像上一節那樣,如果我用“服務引用”的話,vs會偷偷的用svcutil.exe來給我們生成一個proxy類和一個config文件,proxy類也就是你看到的xxxclient。。。
可惡的是config里面會給我生成一些亂七八糟的東西,如下圖:
~~~
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="NetTcpBinding_IHomeService" />
</netTcpBinding>
</bindings>
<client>
<endpoint address="net.tcp://localhost:1920/HomeService" binding="netTcpBinding"
bindingConfiguration="NetTcpBinding_IHomeService" contract="HomeServiceReference.IHomeService"
name="NetTcpBinding_IHomeService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
</client>
</system.serviceModel>
</configuration>
~~~
同服務器端一樣,如果我用code做掉,是不是非常的爽呢???那可不可以做掉呢? 我們還得看一下proxy的源碼,首先你會看到其實所謂的proxy只是一個繼承
自clientbase的一個類,如下圖。
?
上面的兩幅圖,你會發現,最后的proxy類是通過ChannelFactory類來完成助攻的,那話說回來了,既然底層用了ChannelFactory,
那何不我在代碼里面就用ChannelFactory不是更好嗎???這樣config也省了,對吧,說干就干啦。。。
~~~
static void Main(string[] args)
{
ChannelFactory<IHomeService> factory = new ChannelFactory<IHomeService>(new NetTcpBinding(), "net.tcp://localhost:1920/homeservice");
var channel = factory.CreateChannel();
var result = channel.GetLength("12345");
}
~~~
好了,代碼就這么簡單,現在是不是感覺自己萌萌大啦~~~
- 第一天 三種Binding讓你KO80%的業務
- 第二天 告別煩惱的config配置
- 第三天 client如何知道server提供的功能清單
- 第四天 你一定要明白的通信單元Message
- 第五天 你需要了解的三個小技巧
- 第六天 你必須要了解的3種通信模式
- 第七天 Close和Abort到底該怎么用才對得起觀眾
- 第八天 對“綁定”的最后一點理解
- 第九天 高級玩法之自定義Behavior
- 第十天 學會用SvcConfigEditor來簡化配置
- 第十一天 如何對wcf進行全程監控
- 第十二天 說說wcf中的那幾種序列化
- 第十三天 用WCF來玩Rest
- 第十四天 一起聊聊FaultException
- 終結篇 那些你需要注意的坑