WCF 服務無法獨立存在,它必須駐留於一個 Windows 進程當中,我們把這個 Windows 進程稱之爲 host 進程。一個 host 進程之中可以駐留多個 WCF 服務,而一個 WCF 服務也可以在多個 host 進程中存在,host 進程甚至同時也可以是 WCF 的客戶端進程。Host 進程則可以通過 IIS、WAS(Windows Vista)駐留或者也可以是應用程序的一部分(自行開發)。
IIS hosting
駐留於 IIS 的主要優點在於 host 進程會在客戶端首次請求服務時啓動和由 IIS 來管理 host 進程的生命週期。缺點則是一旦選擇了駐留於 IIS 那麼就只能選擇 HTTP 來進行數據傳輸了,而如果駐留於 IIS5 的話,另一個限制則是所有的服務都只能使用相同的端口號。
下面是創建一個 IIS hosting 的步驟:
1. 在 VS2005 中創建一個 Web 站點(WCF Service)
2. 修改該站點下面的 .svc 文件
<% @ServiceHost Language="C#"
Debug="true"
Service="Anrs.Service.AnrsService"
CodeBehind="~/App_Code/Services/AnrsService.cs" %>
.svc 文件的內容非常簡單,就是標識服務及服務所在的文件。這裏需要注意的就是服務的名字空間是 ServiceContract 特性中指定的名字空間,而不是接口所在的名字空間。
3. 修改 Web.config 配置文件
< configuration xmlns = " http://schemas.microsoft.com/.NetConfiguration/v2.0 " >
< system.serviceModel >
< services >
< service name = " Anrs.Service.AnrsService " behaviorConfiguration = " returnFaults " >
< endpoint contract = " Anrs.Service.IAnrsServiceContract1 " binding = " wsHttpBinding " />
</ service >
</ services >
< behaviors >
< serviceBehaviors >
< behavior name = " returnFaults " >
< serviceDebug includeExceptionDetailInFaults = " true " />
</ behavior >
</ serviceBehaviors >
</ behaviors >
</ system.serviceModel >
< system.web >
< compilation debug = " true " />
</ system.web >
</ configuration >
同 .svc 文件一樣,需要注意 service 節點的 name 屬性值指定的名字空間。所有設置 OK 以後,如果在瀏覽器中訪問 .svc 文件就能看到下面這樣的效果。
Self-Hosting
在 VS2005 中創建一個 Self-Hosting 也是非常簡單的,下面是一個典型的 Console Self-Hosting 的例子。
using System.ServiceModel;
namespace Anrs.Service
{
class Program
{
static void Main( string [] args)
{
Uri baseAddress = new Uri( " http://localhost:8086/ " );
ServiceHost sh = new ServiceHost( typeof (AnrsService), baseAddress);
sh.Open();
Console.Write( " Press any key to exit " );
Console.ReadLine();
sh.Close();
}
}
}
ServiceHost 類派生於 ServiceHostBase 抽象類,後者又派生於 CommunicationObject 抽象類,而 CommunicationObject 則實現了 ICommunicationObject 接口。下面是 ICommunicationObject 接口的定義:
{
void Open();
void Close();
void Abort();
event EventHandler Closed;
event EventHandler Closing;
event EventHandler Faulted;
event EventHandler Opened;
event EventHandler Opening;
IAsyncResult BeginClose(AsyncCallback callback, object state);
IAsyncResult BeginOpen(AsyncCallback callback, object state);
void EndClose(IAsyncResult result);
void EndOpen(IAsyncResult result);
CommunicationState State
{ get ;}
// More members
}
public enum CommunicationState
{
Created,
Opening,
Opened,
Closing,
Closed,
Faulted
}
接口中定義了 BeginClose/BeginOpen 這兩個方法,通過調用這兩個方法,可以在 open/close 服務時異步地進行一些操作。