接上面的章節,我們這篇要講解的是Pipeline是執行的各種事件,我們知道,在自定義的HttpModule的Init方法裡,我們可以添加自己的事件,比如如下代碼:
public class Test : IHttpModule { public void Init(HttpApplication context) { context.BeginRequest += new EventHandler(context_BeginRequest); context.AuthenticateRequest += new EventHandler(context_AuthenticateRequest); } void context_AuthenticateRequest(object sender, EventArgs e) { throw new NotImplementedException(); } void context_BeginRequest(object sender, EventArgs e) { throw new NotImplementedException(); } }
然後添加的代碼,在Pipeline裡執行的時候就會把這些事件給執行了,那麼如何執行並且按照什麼順序執行的呢? 在了解這些之前,我們先看看這些事件是如何在HttpApplication裡暴露出來了,添加事件存放在何處的呢?閱讀HttpApplication 的源碼,我們可以看到,所有的事件都是按照如下的形式暴露的,選擇其中兩個看一下:
/// <devdoc><para>[To be supplied.]</para></devdoc> public event EventHandler BeginRequest { add { AddSyncEventHookup(EventBeginRequest, value, RequestNotification.BeginRequest); } remove { RemoveSyncEventHookup(EventBeginRequest, value, RequestNotification.BeginRequest); } } /// <devdoc><para>[To be supplied.]</para></devdoc> public event EventHandler AuthenticateRequest { add { AddSyncEventHookup(EventAuthenticateRequest, value, RequestNotification.AuthenticateRequest); } remove { RemoveSyncEventHookup(EventAuthenticateRequest, value, RequestNotification.AuthenticateRequest); } }
可以發現,所有的事件都是調用AddSyncEventHookup方法添加進去的,其中第一個參數是以Event+事件名稱的值,這個值是如何得來的,我們找到聲明的代碼:
private static readonly object EventDisposed = new object(); private static readonly object EventErrorRecorded = new object(); private static readonly object EventPreSendRequestHeaders = new object(); private static readonly object EventPreSendRequestContent = new object(); private static readonly object EventBeginRequest = new object(); private static readonly object EventAuthenticateRequest = new object(); private static readonly object EventDefaultAuthentication = new object(); private static readonly object EventPostAuthenticateRequest = new object(); private static readonly object EventAuthorizeRequest = new object(); private static readonly object EventPostAuthorizeRequest = new object(); private static readonly object EventResolveRequestCache = new object(); private static readonly object EventPostResolveRequestCache = new object(); private static readonly object EventMapRequestHandler = new object(); private static readonly object EventPostMapRequestHandler = new object(); private static readonly object EventAcquireRequestState = new object(); private static readonly object EventPostAcquireRequestState = new object(); private static readonly object EventPreRequestHandlerExecute = new object(); private static readonly object EventPostRequestHandlerExecute = new object(); private static readonly object EventReleaseRequestState = new object(); private static readonly object EventPostReleaseRequestState = new object(); private static readonly object EventUpdateRequestCache = new object(); private static readonly object EventPostUpdateRequestCache = new object(); private static readonly object EventLogRequest = new object(); private static readonly object EventPostLogRequest = new object(); private static readonly object EventEndRequest = new object();
再結合add和remove方法,可以大膽猜想,這些值應該是作為key值用的,我們先看完第2個參數,再來驗證我們的猜想,第2個參數是枚舉類型 RequestNotification,這裡我們再猜想一下,所有的事件都應該放在統一的地方,然後用這個枚舉來區分。讓我們先看看這個枚舉類的代碼:
[Flags] public enum RequestNotification { BeginRequest = 1, AuthenticateRequest = 2, AuthorizeRequest = 4, ResolveRequestCache = 8, MapRequestHandler = 16, AcquireRequestState = 32, PreExecuteRequestHandler = 64, ExecuteRequestHandler = 128, ReleaseRequestState = 256, UpdateRequestCache = 512, LogRequest = 1024, EndRequest = 2048, SendResponse = 536870912, }
發現什麼了沒有?雖然使用了Flags標記來記錄以便進行異或查詢,但是這裡的枚舉類型好像少了一些吧,仔細對照代碼發現所有以Post開頭的事件都沒出現在這個枚舉類裡,為什麼呢?那這些事件是如何聲明的?回到HttpApplication類來繼續查看代碼,
/// <devdoc><para>[To be supplied.]</para></devdoc> public event EventHandler PostAuthenticateRequest { add { AddSyncEventHookup(EventPostAuthenticateRequest, value, RequestNotification.AuthenticateRequest, true); } remove { RemoveSyncEventHookup(EventPostAuthenticateRequest, value, RequestNotification.AuthenticateRequest, true); } }