WCF的全稱是:Windows Commnication Foundation.WCF,是微軟對一系列產業標准定義的實現,是面向服務實現的比較好的途徑。傳統的三層結構模式一般為:數據訪問層、業務邏輯層、客戶層,但是這種模式下客戶層與業務邏輯層的耦合較為緊密,而面向服務則使得客戶層跟業務邏輯上實現松耦合。
地址
WCF的每個服務都需要有一個地址的,而且只能有一個,WCF支持多種傳輸:
1.HTTP
2.TCP
3.對等網
4.內部進程通信
5.MSMQ
通常的地址包括兩個方面:1.服務位置、2.傳輸的協議。如基於tcp的地址:net.tcp://localhost:8800/Henllyee.Service,在這裡net.tcp就是傳輸的協議,而後面就是告訴服務的位置。
契約
WCF所有的服務都是公開為契約,當你使用這個服務是就比約遵循一定的契約。契約的表示就想webservice裡的表示,也是通過屬性標簽來標識的。WCF定義了四種契約類型:
1.服務契約(Service Contract):定義客戶端能夠執行的服務操作。
2.數據契約(Data Contract):定義於服務交互的數據類型。
3.錯誤契約(Fault Contract):定義拋出的錯誤。
4.消息契約(Message Contract):定義直接與服務交互的消息。
服務契約是要廣泛使用的,定義個服務契約是很簡單的,只是在一些服務接口上進行標識即可。
namespace HenllyeeWCF.Service { [ServiceContract(Namespace="http://henllyee.cnblogs.com")] public interface IHello { [OperationContract] string SayHello(string strName); } public class Hello:IHello { public string SayHello(string strName) { return String.Format("{0} say hello at {1}", strName, DateTime.Now.ToString()); } } }
首先我們要在接口或則類上標識為"ServiceContract",其中有兩個可選的參數:"Namespace"、"Name",即指定命名空間跟類或則接口的名稱。而即使是應用了ServiceContract,也不是類型的成員就是契約中的,還必須顯示的用OperationContract來暴露操作,為了方便重載,OperationContract提供了可選參數:Name來指定暴露操作的另外的名稱。
注意點:服務契約只能定義在接口或者類上,OperationContract只能應用到方法上。建議服務契約定義在接口上面。
托管
每個WCF的服務必須托管在進程中,每個托管進程可以托管多個服務,而每個服務也可以由多個進程托管。托管可以有幾種:
1.IIS托管。IIS托管可以在客戶端請求是啟動,不需一直啟動,但它只能使用HTTP協議。
2.自托管。必須手工通過程序來控制托管的啟動跟關閉。
3.WAS。只使用Vista,跟IIS托管一樣,但並不局限於HTTP。
下面寫一個自托管的控制台程序:
namespace HenllyeeWCF.Host { class Program { static void Main(string[] args) { using (ServiceHost host = new ServiceHost(typeof(HenllyeeWCF.Service.Hello))) { host.AddServiceEndpoint(typeof(HenllyeeWCF.Service.IHello), new NetTcpBinding(), "net.tcp://localhost:8000/Hello"); host.Open(); Console.Read(); } } } }
WCF客戶端跟服務器端的交互一般是采用EndPoint來交互的,每個EndPoint是由Address(地址)、Binding(綁定)、Contract(契約)組成的。而服務器端是通過暴露EndPoint來交互的。在程序中首先我們定義了一個ServiceHost,同時指定了服務為我們已經定義的HenllyeeWCF.Service.Hello,同時跟host添加一個終節點,然後打開host,等待用戶取消進程。
客戶端
首先,入門啟動host後可以通過,在客戶端添加服務應用的方式來實現服務的調用。也可以自己編程的方式來實現。
namespace HenllyeeWCF.Client { [ServiceContract(Namespace = "http://henllyee.cnblogs.com")] public interface IHello { [OperationContract] string SayHello(string strName); } class Program { static void Main(string[] args) { IHello proxy = ChannelFactory<IHello>.CreateChannel(new NetTcpBinding(), new EndpointAddress("net.tcp://localhost:8000/Hello")); Console.WriteLine(proxy.SayHello("Henllyee Cui")); Console.Read(); } } }
首先我針對服務定義了完全相同的接口,然後通過使用通道ChannelFactory來實現代理,指定綁定、跟EndPoint的地址就可以了。
整個解決方案的體系結構如圖:
然後我們首先來運行下Host,在運行Client端出現效果圖: