上一章分析動態註冊 HttpModule 的實作,本章探討基於該原理的 WebActivator 程式庫。WebActivator 提供三種組件層級屬性,允許在 HttpApplication 初始化前、後及關閉時執行指定靜態方法:
[assembly: WebActivator.PreApplicationStartMethod(typeof(A.InitClass1), "PreStart")] [assembly: WebActivator.PostApplicationStartMethod(typeof(A.InitClass1), "PostStart")] [assembly: WebActivator.ApplicationShutdownMethod(typeof(A.InitClass1), "ShutDown")]
且每種屬性可重複使用(不同於系統內建 PreApplicationStartMethodAttribute 僅能用一次)。
下載 WebActivator 1.5 原始碼(Bitbucket),專案包含 6 個核心 .cs 檔案與 packages.config(參考 Microsoft.Web.Infrastructure.dll)。
PreApplicationStartMethodAttribute、PostApplicationStartMethodAttribute、ApplicationShutdownMethodAttribute 皆繼承 BaseActivationMethodAttribute,標記 [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)],建構子接收型別與方法名稱。
public abstract class BaseActivationMethodAttribute : Attribute {
private Type _type; private string _methodName;
public BaseActivationMethodAttribute(Type type, string methodName) { ... }
public Type Type { get { return _type; } }
public string MethodName { get { return _methodName; } }
public int Order { get; set; }
public void InvokeMethod() {
MethodInfo method = Type.GetMethod(MethodName, BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public);
if (method == null) throw new ArgumentException(...);
method.Invoke(null, null);
}
}
提供 Order 控制同屬性多次使用時的執行順序,InvokeMethod 透過反射呼叫靜態方法。
static class AssemblyExtensions {
public static IEnumerable<T> GetActivationAttributes<T>(this Assembly assembly) where T : BaseActivationMethodAttribute {
return assembly.GetCustomAttributes(typeof(T), inherit: false).OfType<T>();
}
}
用於從組件取得指定啟動屬性集合。WebActivator 透過這些簡潔的類別,實現了靈活的應用程式啟動/關閉鉤子機制,廣泛用於 MVC、Web API 等框架的套件初始化。