mvc源码解读(9)-ActionDescriptor方法Action的描述对象

    上一篇我们在将ControllerDescriptor的时候,顺便提了一下该类里面的FindAction方法,这个方法返回的对象就是ActionDescriptor对象。顾名思义ActionDescriptor就是Action的描述对象,我们知道多个Action方法就组成了一个Controller集合,那么每一个Action就用ActionDescriptor来描述。老规矩我们先来看看ActionDescript里面的一些主要的成员吧:

public abstract string ActionName {get;}

public abstract ControllerDescriptor ControllerDescriptor {get;}

public virtual string UniqueId {get {return _uniqueId.Value;}}

public virtual object[] GetCustomAttributes(bool inherit) {return GetCustomAttributes(typeof(object), inherit);}

public virtual object[] GetCustomAttributes(Type attributeType, bool inherit) {}

 internal virtual IEnumerable<FilterAttribute> GetFilterAttributes(bool useCache) {

           return GetCustomAttributes(typeof(FilterAttribute), inherit: true).Cast<FilterAttribute>(); 

}

public virtual FilterInfo GetFilters() {return new FilterInfo();}

public abstract ParameterDescriptor[] GetParameters();

通过ActionDescriptor的相关属性我们可以知道和ControllerDescriptor一样,ActionDescriptor也有包含Action的名字,来源于路由信息;同时也包含一个string类型的UniqueId用于标识唯一的Action。并且可以通过GetCustomAttributes方法来获取应用在Action上面的标注特性(在ControllerDescriptor类中也有这个方法,原理都一样)。我们重点来看看GetParameters()这个抽象方法,由类ReflectedActionDescriptor重写了该方法:

//通过方法GetParameters返回的用于描述所有参数的ParameterDescriptor数组,也是通过对Action方法的参数列表进行反射来创建的        

public override ParameterDescriptor[] GetParameters() {            

             ParameterDescriptor[] parameters = LazilyFetchParametersCollection();

            //need to clone array so that user modifications aren't accidentally stored            

             return (ParameterDescriptor[])parameters.Clone();        

}

最终调用的是LazilyFetchParametersCollection(),具体如下:

  private ParameterDescriptor[] LazilyFetchParametersCollection() {
            return DescriptorUtil.LazilyFetchOrCreateDescriptors<ParameterInfo, ParameterDescriptor>(
                ref _parametersCache /* cacheLocation */,
                MethodInfo.GetParameters /* initializer */,
                parameterInfo => new ReflectedParameterDescriptor(parameterInfo, this) /* converter */);
        }

这里涉及到另外的一个类ReflectedParameterDescriptor,该类继承了ParameterDescriptor抽象类,ParameterDescriptor和ActionDescriptor,ControllerDescriptor类一样,都是包含了对应的参数,方法和控制器的相关信息。和ControllerDescriptor一样,我们也只需要了解ActionDescriptor包含的信息即可,后面我们将会重点介绍ParameterDescriptor类。

    这样的话,在ControllerActionInvoker中的InvokeAction方法中我们就可以根据FindAction方法获取到了ActionDescriptor对象。

posted @ 2013-02-17 16:18  肖&申&克  阅读(341)  评论(0编辑  收藏  举报