首页 > 代码库 > ASP.NET MVC 描述类型(一)

ASP.NET MVC 描述类型(一)

ASP.NET MVC 描述类型()

前言

在前面的好多篇幅中都有提到过ControllerDescriptor类型,并且在ASP.NET MVC 过滤器()篇幅中简单的描述过,今天我们就来讲一下ControllerDescriptor类型。

 

ControllerDescriptor类型的由来

ASP.NET MVC 过滤器()篇幅中有过示意图,当时说明了在生成过滤器信息对象集合之前所要做的一些步骤中包含着生成ControllerDescriptor类型,并没有详细的说明,我们先来看一下图1

1

wKiom1PGj_aR6n7pAAK9X-kV09Y273.jpg

关于这个示意图之前的一些部分我就不细说了,我们就先看一下ControllerDescriptor类型的生成过程,

从图1中可以看出ControllerDescriptor类型的由来是由ControllerDescriptorCache控制器描述类型缓存类【系统默认实现类】来生成的,ControllerDescriptorCache类型也是实现了ReaderWriterCache<Type,ControllerDescriptor>类型的,这里只要描述一下ReaderWriterCache<Type, ControllerDescriptor>类型中的实现就好了,因为ControllerDescriptorCache也只是调用了基类的某个函数来实现生成的功能。来说实现,ReaderWriterCache<Type,ControllerDescriptor>中有个键值队类型的缓存变量【下文中都用缓存一词代替】,用来存贮控制器描述类型的,实现方法的签名和ControllerDescriptorCacheGetDescriptor()方法一样,第一个参数是会根据当前ControllerContext中的Controller来获取当前控制器的类型,第二个参数暂且不谈稍后讲解现在只要把第二个参数是当成生成ControllerDescriptor类型的外插模块,在实现中,首先会根据ControllerType去缓存中查找,如果有的话则返回查找到的控制器描述类型,没有的话,则会根据第二个参数来生成控制器描述类型,然后会先把生成的控制器描述类型设置到缓存中再返回生成的类型。

看到这里有的朋友会问说来说去也没说重点,ControllerDescriptor类型到底怎么来的,对的,重点在于第二个参数,上面的描述只是让大家更清晰的认识到Func<ControllerDescriptor>的重要性。

看一下系统的默认实现Func<ControllerDescriptor>的方式: () => newReflectedControllerDescriptor(controllerType)controllerType类型是从当前ControllerContext.Controller.GetType()获取的。

对于ReflectedControllerDescriptor类型,在默认实现中都是把它作为ControllerDescriptor类型类使用的。

这个时候我们看一下ControllerDescriptor类型的定义,示例代码1-1.

public abstract class ControllerDescriptor: ICustomAttributeProvider,IUniquelyIdentifiable
    {
 
        protectedControllerDescriptor();
 
        // 摘要:
        //     获取控制器的名称。
        //
        // 返回结果:
        //     控制器的名称。
        public virtual stringControllerName { get; }
        //
        // 摘要:
        //     获取控制器的类型。
        //
        // 返回结果:
        //     控制器的类型。
        public abstract TypeControllerType { get; }
        public virtual stringUniqueId { get; }
 
        // 摘要:
        //     使用指定的名称和控制器上下文来查找操作方法。
        //
        // 参数:
        //   controllerContext:
        //     控制器上下文。
        //
        //   actionName:
        //     操作的名称。
        //
        // 返回结果:
        //     有关操作方法的信息。
        public abstract ActionDescriptorFindAction(ControllerContextcontrollerContext, string actionName);
        //
        // 摘要:
        //     在控制器中检索操作-方法描述符的列表。
        //
        // 返回结果:
        //     控制器中的操作-方法描述符的列表。
        public abstract ActionDescriptor[]GetCanonicalActions();
        public virtual object[]GetCustomAttributes(bool inherit);
        public virtual object[]GetCustomAttributes(Type attributeType, bool inherit);
        public virtual boolIsDefined(Type attributeType, bool inherit);
    }


在代码1-1中,大家也都是看到了ControllerDescriptor类型的定义是抽象类型,其中ControllerName属性表示着当前控制器上下文中的控制器名称,ControllerType属性是被定义为抽象的了,需要在派生类中的实现的(ReflectedControllerDescriptor类型),FindAction()也是抽象的,看这个方法的返回类型就知道了它是做什么用的了,对于这部分的细节都是在默认实现类ReflectedControllerDescriptor类型中表示,来看ReflectedControllerDescriptor类型的定义,示例代码1-2

代码1-2

public class ReflectedControllerDescriptor : ControllerDescriptor
    {
        //
        // 参数:
        //   controllerType:
        //     控制器的类型。
        //
        // 异常:
        //   System.ArgumentNullException:
        //     controllerType 参数为 null。
        publicReflectedControllerDescriptor(TypecontrollerType);
        public override sealed Type ControllerType { get;}
        public override ActionDescriptorFindAction(ControllerContextcontrollerContext, string actionName);
        public override ActionDescriptor[]GetCanonicalActions();
        public override object[]GetCustomAttributes(bool inherit);
        public override object[]GetCustomAttributes(Type attributeType, bool inherit);
        public override boolIsDefined(Type attributeType, bool inherit);
}


对于ReflectedControllerDescriptor类型的具体实现,在这里只是简要的说明一下,ReflectedControllerDescriptor类型的构造函数参数为Type类型,这里上面也说过这是Controller类型,在构造函数构造的时候,ReflectedControllerDescriptor类型内部还有个ActionMethodSelector类型的私有变量,ActionMethodSelector类型的构造函数所需参数也是Type类型。这里为什么要说到ActionMethodSelector类型呢?因为在ReflectedControllerDescriptor类型的FindAction()方法的具体实现中使用的就是ActionMethodSelector类型中的方法。就如图1所示的那样。



本文出自 “金源” 博客,请务必保留此出处http://jinyuan.blog.51cto.com/8854733/1439207