WCF的全稱是Windows Communication Foundation,從英文名稱上看,WCF就是基於Windows下一種通訊的基礎架構。利用WCF能夠實現基於Windows下的各種通訊技術的開發以及應用。WCF是面向服務的,它是構建面向服務的系統設計。簡化實現SOA的方法。WCF也是松耦合,並沒有限制在特定協議、編碼格式、或者主機環境上。還有WCF所有的選項都是可配置的。WCF也提供了非常好的可交互性,主要體現在兩個方面,一個是支持Web Service的核心標准,另一個是在可擴展性方面能夠快速適用新協議和更新。WCF強調了整合性,整合了Microsoft早期期技術。如COM、Enterprise Services,MSMQ。
本文就介紹下WCF入門以及宿主如何調用WCF服務。在這個例子中我們將使用VS 2012 創建一個WCF服務,其中會了解[DataContract] [ServiceContract] 等的特性以及通過內置的 WCFSVCHost ,並使用“WCF測試客戶端”來測試我們創建的服務。最終在不同的宿主上調用該WCF。
注意下面的所有類、接口及方法都添加了public 的訪問級別。
1、 創建WCF服務庫,如下圖所示

在解決方案中會自動為我們生成兩個類文件“IService.cs”和“Service.cs”。這兩個類文件是兩個WCF示例文件,對我們開發沒有什么用處,現在我們刪掉這兩個文件。
2、新建類文件
在彈出的“添加新項”窗口中,選擇“類”,並在“名稱”文本框中寫入項名稱“Person.cs”。
同時也要創建服務接口,聲明對外發布的類和方法,名稱為“IPersonService.cs”,再創建“PersonService.cs” 如下圖所示:

其中,Person.cs提供所需要的模型。代碼如下:
using System.Runtime.Serialization; namespace WcfServiceLibrary1 { [DataContract] public class Person { [DataMember] public string Id; [DataMember] public string Name; [DataMember] public int Age; } }
IPersonService.cs文件創建服務接口,聲明對外發布的類和方法。代碼如下:
using System.Collections.Generic; using System.ServiceModel; namespace WcfServiceLibrary1 { /// <summary> /// ServiceContract:服務約定,代表我們所能操作的接口集合,提供功能點。 /// 在IPersonService接口上面,我們定義了[ServiceContract]標簽,此標簽代表此接口及實現此接口的類都是對外發布的Service類, /// 在每個需要對外發布的方法上都加上[OperationContract]標簽,以使外部可以訪問到此方法。 /// [ServiceContract]和[OperationContract]這兩個標簽需要導入using System.ServiceModel命名空間。 /// </summary> [ServiceContract] public interface IPersonService { /// <summary> /// OperationContract 操作約定,定義每個操作的接口點方法。 /// </summary> [OperationContract] void AddPerson(Person person); /// <summary> /// 獲取所有的實體的方法 /// </summary> /// <returns></returns> [OperationContract] List<Person> GetAllPersons(); /// <summary> /// 刪除某個實體的方法 /// </summary> /// <param name="id">實體id</param> [OperationContract] void RemovePerson(string id); } }
PersonService.cs文件實現我們上面聲明的服務接口,實現對Person的添加、刪除和檢索的具體功能。代碼如下:
using System; using System.Collections.Generic; using System.ServiceModel; namespace WcfServiceLibrary1 { /// <summary> /// 此類是對IBookService接口的具體實現,在此類的上面我們聲明了[ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)]標簽, /// 此標簽代表這個類采用SingleTone(單類模式)來生成對象。 /// 使用[ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)]接口需要導入using System.ServiceModel;命名空間。 /// </summary> [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)] public class PersonService : IPersonService { List<Person> _Persons = new List<Person>(); public void AddPerson(Person person) { person.Id = Guid.NewGuid().ToString(); _Persons.Add(person); } public List<Person> GetAllPersons() { return _Persons; } public void RemovePerson(string id) { Person person = _Persons.Find(p => p.Id == id); _Persons.Remove(person); } } }
然后進行編譯。
3、配置服務並運行
到目前為至,我們建立好了WCF服務,那我們如何讓WCFSVCHost(WCF服務主機)理解我們編寫的服務類,並能夠運行我們編寫的服務呢。這需要我們在App.Config里面注冊一下我們的WCF服務。
VS為我們提供了可視化的操作界面。
在項目中右擊“App.Config”配置文件,在彈出的郵件菜單中選擇“編輯WCF配置”,並打開,如下圖所示:

在此界面中暴露兩個對外的終結點(外部可以訪問到的類或接口),其中下面一個是元數據終結點,用來向外提供服務信息的終結點。而另一個(即上面的終結點),是向外公布我們編寫的[ServiceContract]的類,但我們可以看到它的Contract還是我們在第一步中刪掉的WcfServiceLibrary1.IService1這個終結點。
不僅如此,在右側上面的黑字的服務中還依舊是我們在第一步中刪除的WcfServiceLibrary1.Service1服務。這說明雖然在第一步中我們刪除了那兩個自動生成的類文件,但配置文件中仍沒有刪除這兩個類文件的配置信息。
下面我們把它們改變一下。
單擊左側的“服務”-“WcfServiceLibrary1.Service1”在右側的Name,彈出“服務類型瀏覽器”對話框,在此類型中我們找到此WCF服務項目編譯出來的WcfServiceLibrary1.dll文件,雙擊它就可以出現此服務中的對外公布的服務,點擊選中它單擊確定。如下圖所示:

這樣我們就可以把對外公司的服務改變為我們剛編寫的服務了。
然后,我們展開左側“服務”->“WcfServiceLibrary1.PersonService”->“終結點”,單擊第一個“空名稱”,從右邊的“終結點屬性”中的Contract中我們可以看到,這里的Contract仍然用的是WcfServiceLibrary1.IService1。如下圖所示:

我們按照上面的做法,找到此WCF服務項目編譯出來的WcfServiceLibrary1.dll,雙擊它找到里面對應的ServiceContract點擊確定就可以了。
重點一定要記着保存,點擊菜單“文件”-“保存”就可以把我們對App.Config的修改保存回配置文件了。
App.Config代碼如下:
<?xml version="1.0" encoding="utf-8" ?> <configuration> <appSettings> <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" /> </appSettings> <system.web> <compilation debug="true" /> </system.web> <!-- 部署服務庫項目時,必須將配置文件的內容添加到 主機的 app.config 文件中。System.Configuration 不支持庫的配置文件。--> <system.serviceModel> <services> <service name="WcfServiceLibrary1.PersonService"> <endpoint address="" binding="basicHttpBinding" contract="WcfServiceLibrary1.IPersonService"> <identity> <dns value="localhost" /> </identity> </endpoint> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> <host> <baseAddresses> <add baseAddress="http://localhost:8733/Design_Time_Addresses/WcfServiceLibrary1/Service1/" /> </baseAddresses> </host> </service> </services> <behaviors> <serviceBehaviors> <behavior> <!-- 為避免泄漏元數據信息, 請在部署前將以下值設置為 false --> <serviceMetadata httpGetEnabled="True" httpsGetEnabled="True"/> <!-- 要接收故障異常詳細信息以進行調試, 請將以下值設置為 true。在部署前設置為 false 以避免泄漏異常信息--> <serviceDebug includeExceptionDetailInFaults="False" /> </behavior> </serviceBehaviors> </behaviors> </system.serviceModel> </configuration>
4、通過WCFSVCHost 來測試WCF服務
在Visual Studio 中為我們提供了測試WCF的工具,按F5啟動WCF會出現兩個東西:
一個是在右下角的托盤圖標中會出現WCFSVCHost(WCF服務主機),它為我們在開發時候提供了一個運行WCF的服務器,用來為測試客戶端提供WCF服務。如下圖所示:

另一個是“WCF測試客戶端”
“測試客戶端”從WcfSVCHost中取得WCF服務的元數據,解析為左側的“服務結構樹”,從這里面我們可以看到此WCF服務為我們提供了一個服務契約“IPersonService”,此服務契約中對外提供了三個可調用的方法。如下圖所示:

然后我們可以通過服務方法來測試。點擊不同的方法進行測試,如下圖所示:

在本例中我們看到,WCF作為面向對象和面向服務的橋梁 ,提供了非常方便的工具,無論是開發,配置還是測試,為我們可以快速的上手並提供面向服務的應用。你可以把WCF類庫當作普通類庫去做,但他提供了更強大的面向服務的特性。
5、后話
WCF的理論學習復雜程度遠大於其的使用難度,而如果你是一名初學者,千萬不要先陷入其復雜的理論學習中,花費很多的時間,而且看得暈頭轉向,最好先去實踐,先去用,這樣再去看WCF的深入概念和技術才會在大腦里面形成更好理解的印象和對應。下講說明如何通過宿主來調用WCF服務。如果各位有疑問或者指教,請留言或者加群225109172,共同學習進步。
