WebActivator的实现原理详解

上篇文章,我们分析如何动态注册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>();  
        }  
    }  
}




转载请注明:http://www.shhjfk.com/xxzl/xxzl/15.html

  • 上一篇文章: 没有了
  •   
  • 下一篇文章: