在前面的好多篇幅中都有提到過ControllerDescriptor類型,而且在ASP.NET MVC 過濾器(一)篇幅中簡單的描述過,今天咱們就來說一下ControllerDescriptor類型。緩存
在ASP.NET MVC 過濾器(一)篇幅中有過示意圖,當時說明了在生成過濾器信息對象集合以前所要作的一些步驟中包含着生成ControllerDescriptor類型,並無詳細的說明,咱們先來看一下圖1ide
圖1函數
關於這個示意圖以前的一些部分我就不細說了,咱們就先看一下ControllerDescriptor類型的生成過程;spa
從圖1中能夠看出ControllerDescriptor類型的由來是由ControllerDescriptorCache控制器描述類型緩存類【系統默認實現類】來生成的,ControllerDescriptorCache類型也是實現了ReaderWriterCache<Type, ControllerDescriptor>類型的,這裏只要描述一下ReaderWriterCache<Type, ControllerDescriptor>類型中的實現就行了,由於ControllerDescriptorCache也只是調用了基類的某個函數來實現生成的功能。來講實現,ReaderWriterCache<Type, ControllerDescriptor>中有個鍵值隊類型的緩存變量【下文中都用緩存一詞代替】,用來存貯控制器描述類型的,實現方法的簽名和ControllerDescriptorCache的GetDescriptor()方法同樣,第一個參數是會根據當前ControllerContext中的Controller來獲取當前控制器的類型,第二個參數暫且不談稍後講解如今只要把第二個參數是當成生成ControllerDescriptor類型的外插模塊,在實現中,首先會根據ControllerType去緩存中查找,若是有的話則返回查找到的控制器描述類型,沒有的話,則會根據第二個參數來生成控制器描述類型,而後會先把生成的控制器描述類型設置到緩存中再返回生成的類型。code
看到這裏有的朋友會問說來講去也沒說重點,ControllerDescriptor類型到底怎麼來的,對的,重點在於第二個參數,上面的描述只是讓你們更清晰的認識到Func<ControllerDescriptor>的重要性。對象
看一下系統的默認實現Func<ControllerDescriptor>的方式: () => new ReflectedControllerDescriptor(controllerType),controllerType類型是從當前ControllerContext.Controller.GetType()獲取的。blog
對於ReflectedControllerDescriptor類型,在默認實現中都是把它做爲ControllerDescriptor類型類使用的。ip
這個時候咱們看一下ControllerDescriptor類型的定義,示例代碼1-1.get
代碼1-1博客
public abstract class ControllerDescriptor : ICustomAttributeProvider, IUniquelyIdentifiable { protected ControllerDescriptor(); // 摘要: // 獲取控制器的名稱。 // // 返回結果: // 控制器的名稱。 public virtual string ControllerName { get; } // // 摘要: // 獲取控制器的類型。 // // 返回結果: // 控制器的類型。 public abstract Type ControllerType { get; } public virtual string UniqueId { get; } // 摘要: // 使用指定的名稱和控制器上下文來查找操做方法。 // // 參數: // controllerContext: // 控制器上下文。 // // actionName: // 操做的名稱。 // // 返回結果: // 有關操做方法的信息。 public abstract ActionDescriptor FindAction(ControllerContext controllerContext, string actionName); // // 摘要: // 在控制器中檢索操做-方法描述符的列表。 // // 返回結果: // 控制器中的操做-方法描述符的列表。 public abstract ActionDescriptor[] GetCanonicalActions(); public virtual object[] GetCustomAttributes(bool inherit); public virtual object[] GetCustomAttributes(Type attributeType, bool inherit); public virtual bool IsDefined(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。 public ReflectedControllerDescriptor(Type controllerType); public override sealed Type ControllerType { get; } public override ActionDescriptor FindAction(ControllerContext controllerContext, string actionName); public override ActionDescriptor[] GetCanonicalActions(); public override object[] GetCustomAttributes(bool inherit); public override object[] GetCustomAttributes(Type attributeType, bool inherit); public override bool IsDefined(Type attributeType, bool inherit); }
對於ReflectedControllerDescriptor類型的具體實現,在這裏只是簡要的說明一下,ReflectedControllerDescriptor類型的構造函數參數爲Type類型,這裏上面也說過這是Controller類型,在構造函數構造的時候,ReflectedControllerDescriptor類型內部還有個ActionMethodSelector類型的私有變量,ActionMethodSelector類型的構造函數所需參數也是Type類型。這裏爲何要說到ActionMethodSelector類型呢?由於在ReflectedControllerDescriptor類型的FindAction()方法的具體實現中使用的就是ActionMethodSelector類型中的方法。就如圖1所示的那樣。
做者:金源
出處:http://www.cnblogs.com/jin-yuan/
本文版權歸做者和博客園共有,歡迎轉載,但未經做者贊成必須保留此段聲明,且在文章頁面