程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> ASP.NET >> 關於ASP.NET >> MVC系列(7) WebActivator的實現原理詳解

MVC系列(7) WebActivator的實現原理詳解

編輯:關於ASP.NET

上篇文章,我們分析如何動態注冊HttpModule的實現,本篇我們來分析一下通過上篇代碼原理實現的WebActivator類庫,WebActivator提供了3種功能,允許我們分別在HttpApplication初始化之前,之後以及ShutDown的時候分別執行指定的代碼,示例如下:

[assembly: WebActivator.PreApplicationStartMethod(typeof(A.InitClass1), "PreStart")]  
[assembly: WebActivator.PostApplicationStartMethod(typeof(A.InitClass1), "PostStart")]  
[assembly: WebActivator.ApplicationShutdownMethod(typeof(A.InitClass1), "ShutDown")]

另外還有一點和系統自帶的PreApplicationStartMethodAttribute不同的是,WebActivator的每種特性都可以使用多次,比如:

[assembly: WebActivator.PreApplicationStartMethod(typeof(A.InitClass1), "PreStart")]  
[assembly: WebActivator.PreApplicationStartMethod(typeof(A.InitClass2), "PreStart")]  
[assembly: WebActivator.PreApplicationStartMethod(typeof(A.InitClass3), "PreStart")]

因為它的源碼很少,所以今天我們就來全面分析一下WebActivator的實現原理,首先下載WebActivator的最新1.5源碼,源碼地址:https://bitbucket.org/davidebbo/webactivator/src

解壓代碼,我們可以看到WebActivator項目裡總共有6個重要的cs文件,以及一個packages.config文件(用於標記本項目引用了Microsoft.Web.Infrastructure.dll類庫),下面我們來分析一下每個文件的源碼。

3個XXXMethodAttribute屬性:

根據上面的用法,我們指導WebActivator提供了3個MethodAttribute,我們先來看看這3個文件都是如何實現的,查閱代碼發現3個類(PreApplicationStartMethodAttribute/ PostApplicationStartMethodAttribute/ ApplicationShutdownMethodAttribute)的內容都是一樣的,都是繼承於 BaseActivationMethodAttribute類,然後提供構造函數所需要的Type類型和方法名稱, 3個特性類都支持使用多次並且只能用於Assembly,代碼如下:

[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]

通用的基類BaseActivationMethodAttribute:

using System;  
using System.Reflection;  
      
namespace WebActivator  
{  
    // Base class of all the activation attributes  
    [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]  
    public abstract class BaseActivationMethodAttribute : Attribute  
    {  
        private Type _type;  
        private string _methodName;  
      
        public BaseActivationMethodAttribute(Type type, string methodName)  
        {  
            _type = type;  
            _methodName = methodName;  
        }  
      
        public Type Type { get { return _type; } }  
      
        public string MethodName { get { return _methodName; } }  
      
        public int Order { get; set; }  
      
      
        public void InvokeMethod()  
        {  
            // Get the method  
            MethodInfo method = Type.GetMethod(  
                MethodName,  
                BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public);  
      
            if (method == null)  
            {  
                throw new ArgumentException(  
                    String.Format("The type {0} doesn't have a static method named {1}",  
                        Type, MethodName));  
            }  
      
            // Invoke it  
            method.Invoke(null, null);  
        }  
    }  
}

通過代碼,我們首先可以看到,除了Type和MethodName以外,還多了一個Order屬性,用來標記多次使用同一個Attribute的時候的執行順序。然後提供了一個InvokeMethod方法,用來執行該類裡傳入當前Type類的MethodName靜態方法。

Assembly擴展方法AssemblyExtensions:

using System.Collections.Generic;  
using System.Linq;  
using System.Reflection;  
      
namespace WebActivator  
{  
    static class AssemblyExtensions  
    {  
        // Return all the attributes of a given type from an assembly  
        public static IEnumerable<T> GetActivationAttributes<T>(this Assembly assembly) where T : BaseActivationMethodAttribute  
        {  
            return assembly.GetCustomAttributes(  
                typeof(T),  
                inherit: false).OfType<T>();  
        }  
    }  
}

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved