序言
註冊Httpmodule可以讓我們使用HttpApplication物件中的處理管道事件。目前大家所熟知的應該有2種方式來使用HttpApplication物件中的處理管道事件。第一種是通過Global.asax全域性檔案,另外一種是通過配置檔案來註冊httpmodule。那麼有這2種方式啦,為什麼還要有今天這篇部落格呢?
這裡我也提1個簡單的問題,用例項來證明下動態註冊httpmodule的可取之處。
如果你要寫一個.net框架,供公司所有mvc專案使用,那麼你的框架整合的眾多功能中,至少應該需要一個異常記錄的功能吧,有啦這個功能之後,別人的專案即便忘記處理異常資訊,那麼框架也會幫忙一個不拉的將專案異常資訊寫入框架的日誌當中,還有你的框架要叼,怎麼叼呢?叼到別人不需要寫如一行程式碼即可實現這樣的功能,哇咔,怎麼實現?在你的框架中,只需要幾行程式碼即可。
Microsoft.Web.Infrastructure.dll與PreApplicationStartMethodAttribute屬性
首先我們利用ilspy來看下Microsoft.Web.Infrastructure.dll這個類庫是幹什麼的,如圖:
[SecuritySafeCritical] public static void RegisterModule(Type moduleType) { if (DynamicModuleReflectionUtil.Fx45RegisterModuleDelegate != null) { DynamicModuleReflectionUtil.Fx45RegisterModuleDelegate(moduleType); return; } DynamicModuleUtility.LegacyModuleRegistrar.RegisterModule(moduleType); }
那看到此類庫的原始碼之後,便可以順藤摸瓜,看清其真面目啦。
- Microsoft.Web.Infrastructure.DynamicModuleHelper 此名稱空間我們可以看出他是關於動態module的helper 。
- DynamicModuleUtility此類便是實用類,那麼開啟之後,便看到啦一個醒目的方法,RegisterModule,註冊Module,沒錯他就是動態註冊HttoModule的方法。
思考一下上面我的命題,是在專案中一行程式碼不用便可執行我們的類庫,那麼動態註冊HttpModule有啦,接下來就是怎麼一行程式碼不寫,就能執行我們的類庫呢?這就用到啦微軟提供的PreApplicationStartMethodAttribute 屬性。
- PreApplicationStartMethodAttribute:此屬性也可以望文生義,便是在application啟動之前要執行的方法。就是說他也是一個程式的入口點,並且還是application初始化之前便啟動啦,萬物之初先有的便是它,造作吧。
- WebActivatorEx:這是一個類庫,微軟提供啦PreApplicationStartMethodAttribute特性,微軟Nuget開發小組有一個成員David Ebbo寫啦這個更叼的類庫,內容如下圖
呢,這個類庫可以動態註冊HttpMoudle,他還實現不修改全域性檔案就可以加入,Application_Start()/Shutdown()事件,原始碼你可以使用ilspy檢視,也有專案的git地址,通過nuget可以獲取,值得你去研究下。
程式碼實現動態註冊HttpMoudle
[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(RoutingCore.PreApplicationStartRegist), "PreStart")] namespace RoutingCore { public class PreApplicationStartRegist { private static bool hasLoaded; public static void PreStart() { if (!hasLoaded) { hasLoaded = true; DynamicModuleUtility.RegisterModule(typeof(RoutingModule)); } } } }
public class RoutingModule : IHttpModule { public void Init(HttpApplication context) { context.BeginRequest += new EventHandler(context_BeginRequest); context.Error += new EventHandler(context_ErrorRequest); } void context_BeginRequest(object sender, EventArgs e) { } void context_ErrorRequest(object sender, EventArgs e) { HttpApplication ap = sender as HttpApplication; var error = ap.Server.GetLastError(); var code = (error is HttpException) ? (error as HttpException).GetHttpCode() : 500; if (code != 404) { } // 寫入本地檔案,佇列或資料庫 // ... ap.Server.ClearError(); ap.Response.Write(error.Message); ap.Response.End(); } public void Dispose() { } }
這個作用遠不止與這裡的異常記錄,對於寫框架來說,他的用處可以說是大大的,你自己參悟吧。
總結
接下來是大家最喜歡的總結內容啦,內容有三,如下:
1、希望能關注我其他的文章。
2、部落格裡面有沒有很清楚的說明白,或者你有更好的方式,那麼歡迎加入左上方的2個交流群,我們一起學習探討。
3、你可以忘記點贊加關注,但千萬不要忘記掃碼打賞哦。