Mvc動態注冊HttpModule詳解


序言

注冊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);
}

那看到此類庫的源碼之后,便可以順藤摸瓜,看清其真面目啦。

  1. Microsoft.Web.Infrastructure.DynamicModuleHelper 此命名空間我們可以看出他是關於動態module的helper 。
  2. DynamicModuleUtility此類便是實用類,那么打開之后,便看到啦一個醒目的方法,RegisterModule,注冊Module,沒錯他就是動態注冊HttoModule的方法。

思考一下上面我的命題,是在項目中一行代碼不用便可執行我們的類庫,那么動態注冊HttpModule有啦,接下來就是怎么一行代碼不寫,就能運行我們的類庫呢?這就用到啦微軟提供的PreApplicationStartMethodAttribute 屬性。

  1. PreApplicationStartMethodAttribute:此屬性也可以望文生義,便是在application啟動之前要運行的方法。就是說他也是一個程序的入口點,並且還是application初始化之前便啟動啦,萬物之初先有的便是它,造作吧。
  2. 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、你可以忘記點贊加關注,但千萬不要忘記掃碼打賞哦。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM