WCF服務(wù)寄宿相關(guān)使用概念詳解
WCF開發(fā)工具是一個建立于.Net Framework 2.0基礎(chǔ)上的一個功能強大的開發(fā)插件,那么如何才能正確的應(yīng)用這一插件來幫助我們在實際開發(fā)中獲得幫助呢?這首先就需要我們來熟練掌握一些應(yīng)用技巧,比如今天為大家介紹的WCF服務(wù)寄宿的相關(guān)內(nèi)容。
在默認(rèn)的情況下,基于IIS的服務(wù)寄宿是通過一個特殊的HttpModule實現(xiàn)的,其類型為System.ServiceModel.Activation.HttpModule,是一個定義在System.ServiceModel程序集中的內(nèi)部類型。HttpModule的定義大體上如下面的代碼所示,我們很清楚地看到其實現(xiàn)的原理:將實現(xiàn)WCF Service請求處理的邏輯注冊到HttpApplication的PostAuthenticationRequest事件中。
- internal class HttpModule : IHttpModule
- {
- //其他成員
- public void Init(HttpApplication context)
- {
- context.PostAuthenticateRequest += new EventHandler
(HttpModule.ProcessRequest);- }
- private static void ProcessRequest
(object sender, EventArgs e)- {
- //服務(wù)請求處理實現(xiàn)
- }
- }
System.ServiceModel.Activation.HttpModule是一個特殊的HttpModule,說它特別是因為當(dāng)HttpModule注冊到HttpApplication的PostAuthenticateRequest事件處理程序執(zhí)行后,不會再將請求進一步分發(fā)給后續(xù)的請求處理步驟。換句話說,就HttpApplication從BeginRequest到EndRequest整個請求處理的生命周期來說,對于基于.svc文件的請求僅僅延續(xù)到PostAuthenticateRequest階段。我們可以通過一種簡單的方式來證明這一點。
假設(shè)我們有一個WCF服務(wù)寄宿需要通過IIS進行寄宿,并把WCF服務(wù)相應(yīng)的.svc文件定義在一個對應(yīng)于某個IIS虛擬目錄的ASP.NET Website中?,F(xiàn)在我們?yōu)橹砑右粋€global.asax,在該global.asax,我通過如下的代碼注冊了HttpApplication處理請求的前三個事件:BeginRequest、AuthenticateRequest和PostAuthenticateRequest,當(dāng)這3個事件觸發(fā)后,將一段代表當(dāng)前事件的名稱寫入EventLog中。
- <%@ Application Language="C#" %>
- <%@ Import Namespace= "System.Diagnostics"%>
- <script runat="server">
- void Application_BeginRequest(object sender, EventArgs e)
- {
- string message = string.Format("BeginRequest Event is
raised at {0}", DateTime.Now);- EventLog.WriteEntry("Application", message,
EventLogEntryType.Information);- }
- void Application_AuthenticateRequest(object sender, EventArgs e)
- {
- string message = string.Format("AuthenticateRequst Event
is raised at {0}",DateTime.Now);- EventLog.WriteEntry("Application", message,
EventLogEntryType.Information);- }
- void Application_PostAuthenticateRequest(object sender, EventArgs e)
- {
- string message = string.Format("PostAuthenticateRequest
Event is raised at {0}", DateTime.Now);- EventLog.WriteEntry("Application", message,
EventLogEntryType.Information);- }
- </script>
如果我們上面的說法成立的話,只有HttpApplication的最初3個事件被觸發(fā)。此外,HttpModule注冊的操作會先于定義在global.asax的Application_PostAuthenticateRequest方法執(zhí)行,那么在整個服務(wù)調(diào)用過程中,只有Application_BeginRequest和Application_AuthenticateRequest這兩個方法會被執(zhí)行。這一點我們可以從EventLog得到證實。當(dāng)我們通過執(zhí)行案例7-2中的代表客戶端應(yīng)用程序后,EventLog中WindowsLog的Application分組中,會多出兩個日志項目(之前已經(jīng)將日志清空)。#t#
日志的內(nèi)容正是我們在Application_BeginRequest和Application_AuthenticateRequest方法中定義的日志文本。可見僅僅這兩個方法被成功執(zhí)行,Application_PostAuthenticateRequest方法卻沒有被執(zhí)行。可以想象,后續(xù)的事件也不可能被觸發(fā)。
到現(xiàn)在為止,我們僅僅是介紹了如何處理基于.svc文件的請求,并沒有說明.svc文件對應(yīng)的WCF Service是如何被寄宿的。WCF服務(wù)寄宿發(fā)生在對服務(wù).svc文件的***次訪問,具體的實現(xiàn)很簡單:ServiceMode根據(jù)請求的目的地址加載相應(yīng)的.svc文件,通過解析定義在<%ServiceHost%>指令的Factory和Service屬性得到ServiceHostFactory和Service的類型(Factory默認(rèn)為System.ServiceMode.ServiceHostFactory),通過反射創(chuàng)建繼承自基類System.ServiceModel.Activation.ServiceHostFactoryBase的ServiceHostFactory對象。***通過ServiceHostFactory創(chuàng)建的繼承自基類System.ServiceModel.ServiceHostBase的ServieHost對象對Serivce進行WCF服務(wù)寄宿。