使用 ServiceHostFactory 擴充裝載
Windows Communication Foundation (WCF) 中裝載服務的標準 ServiceHost API 是 WCF 架構中的擴充點。 使用者可以從 ServiceHost 衍生自己的主機類別,通常要覆寫 OnOpening() 以使用 ServiceDescription 以便在開啟服務之前以命令方式新增預設端點或修改行為。
在自我裝載的環境中,您不需要建立自訂 ServiceHost,因為您會撰寫可具現化主機的程式碼,然後在產生的主機上呼叫 Open()。 您可以在這兩個步驟之間隨心所欲地執行所需的工作。 例如,您可以新增一個 IServiceBehavior:
public static void Main()
{
ServiceHost host = new ServiceHost( typeof( MyService ) );
host.Description.Add( new MyServiceBehavior() );
host.Open();
...
}
這個方法無法重複使用。 用來操控描述的程式碼會寫入主機程式 (在此情況中,為 Main() 函式) 的程式碼中,因此您很難在其他環境中重複使用此邏輯。 您也可以透過其他不需要命令式程式碼的方法,來新增 IServiceBehavior。 您可以從 ServiceBehaviorAttribute 衍生屬性,並將其放在您的服務實作類型中,或是讓自訂行為變成可設定,並透過組態來加以動態撰寫。
但是,您也可以稍微修改一下範例,來解決這個問題。 其中一個方法,就是將可新增 ServiceBehavior 的程式碼從 Main()
移出,並移入 OnOpening 之自訂衍生物的 ServiceHost 方法:
public class DerivedHost : ServiceHost
{
public DerivedHost( Type t, params Uri baseAddresses ) :
base( t, baseAddresses ) {}
public override void OnOpening()
{
this.Description.Add( new MyServiceBehavior() );
}
}
接著,在 Main()
中使用:
public static void Main()
{
ServiceHost host = new DerivedHost( typeof( MyService ) );
host.Open();
...
}
現在您已經將自訂邏輯封裝成完全的抽象概念,可輕易地重複用在許多不同的主機可執行檔上。
現在您可能還無法立即瞭解如何從網際網路資訊服務 (IIS) 或 Windows Process Activation Service (WAS) 的內部使用這個自訂 ServiceHost。 這些環境與自我裝載環境不同,因為裝載環境是指代表應用程式具現化 ServiceHost 的環境。 IIS 和 WAS 裝載基礎結構對於您的自訂 ServiceHost 衍生物一無所知。
ServiceHostFactory 便是用來解決從 IIS 或 WAS 內部存取自訂 ServiceHost 的問題。 因為從 ServiceHost 衍生的自訂主機是動態設定而且可能是各種型別,裝載環境不可能直接加以具現化。 相反地,WCF 使用處理站模式,在裝載環境與實體服務類型之間提供間接取值層。 除非您明確告知,否則它會使用預設的 ServiceHostFactory 實作,以傳回 ServiceHost 執行個體。 但您也可透過在 @ServiceHost 指示詞中指定處理站實作的 CLR 類型名稱,來提供您自己的處理站,以傳回您的衍生主機。
這麼做的用意在於,對於基本案例來說,實作自己的處理站應該會相當簡單。 例如,下列為自訂 ServiceHostFactory (可傳回衍生的 ServiceHost):
public class DerivedFactory : ServiceHostFactory
{
public override ServiceHost CreateServiceHost( Type t, Uri[] baseAddresses )
{
return new DerivedHost( t, baseAddresses )
}
}
若要使用此處理站 (而不是預設處理站),請在 @ServiceHost 指示詞中提供類型名稱,如下所示:
<% @ServiceHost Factory="DerivedFactory" Service="MyService" %>
儘管技術上並未限制您可以對 ServiceHost (從 CreateServiceHost 傳回) 執行的事項,我們建議您盡可能讓處理站的實作保持簡潔。 如果您有太多的自訂邏輯,最好將該邏輯放在自己的主機中 (而不要放在處理站中),以便重複使用。
對於裝載的應用程式開發介面,還有一個值得一提的層級。 WCF 也同時擁有會分別衍生出 ServiceHost 和 ServiceHostFactory 的 ServiceHostBase 和 ServiceHostFactoryBase。 之所以提供這些項目是因為在某些比較進階的情節中,您必須使用自己的自訂建立項目來交換大部分的中繼資料系統。