ASP.NET MVC 描述類型(一)
前言
在前面的好多篇幅中都有提到過ControllerDescriptor類型,并且在ASP.NET MVC 過濾器(一)篇幅中簡單的描述過,今天我們就來講一下ControllerDescriptor類型。
ControllerDescriptor類型的由來
在ASP.NET MVC 過濾器(一)篇幅中有過示意圖,當時說明了在生成過濾器資訊對象集合之前所要做的一些步驟中包含着生成ControllerDescriptor類型,并沒有詳細的說明,我們先來看一下圖1
圖1
<a href="http://s3.51cto.com/wyfs02/M01/3E/3C/wKiom1PGj_aR6n7pAAK9X-kV09Y273.jpg" target="_blank"></a>
關于這個示意圖之前的一些部分我就不細說了,我們就先看一下ControllerDescriptor類型的生成過程,
從圖1中可以看出ControllerDescriptor類型的由來是由ControllerDescriptorCache控制器描述類型緩存類【系統預設實作類】來生成的,ControllerDescriptorCache類型也是實作了ReaderWriterCache<Type,ControllerDescriptor>類型的,這裡隻要描述一下ReaderWriterCache<Type, ControllerDescriptor>類型中的實作就好了,因為ControllerDescriptorCache也隻是調用了基類的某個函數來實作生成的功能。來說實作,ReaderWriterCache<Type,ControllerDescriptor>中有個鍵值隊類型的緩存變量【下文中都用緩存一詞代替】,用來存貯控制器描述類型的,實作方法的簽名和ControllerDescriptorCache的GetDescriptor()方法一樣,第一個參數是會根據目前ControllerContext中的Controller來擷取目前控制器的類型,第二個參數暫且不談稍後講解現在隻要把第二個參數是當成生成ControllerDescriptor類型的外插子產品,在實作中,首先會根據ControllerType去緩存中查找,如果有的話則傳回查找到的控制器描述類型,沒有的話,則會根據第二個參數來生成控制器描述類型,然後會先把生成的控制器描述類型設定到緩存中再傳回生成的類型。
看到這裡有的朋友會問說來說去也沒說重點,ControllerDescriptor類型到底怎麼來的,對的,重點在于第二個參數,上面的描述隻是讓大家更清晰的認識到Func<ControllerDescriptor>的重要性。
看一下系統的預設實作Func<ControllerDescriptor>的方式: () => newReflectedControllerDescriptor(controllerType),controllerType類型是從目前ControllerContext.Controller.GetType()擷取的。
對于ReflectedControllerDescriptor類型,在預設實作中都是把它作為ControllerDescriptor類型類使用的。
這個時候我們看一下ControllerDescriptor類型的定義,示例代碼1-1.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<code>public</code> <code>abstract</code> <code>class</code> <code>ControllerDescriptor: ICustomAttributeProvider,IUniquelyIdentifiable</code>
<code> </code><code>{</code>
<code> </code>
<code> </code><code>protectedControllerDescriptor();</code>
<code> </code><code>// 摘要:</code>
<code> </code><code>// 擷取控制器的名稱。</code>
<code> </code><code>//</code>
<code> </code><code>// 傳回結果:</code>
<code> </code><code>// 控制器的名稱。</code>
<code> </code><code>public</code> <code>virtual</code> <code>stringControllerName { </code><code>get</code><code>; }</code>
<code> </code><code>// 擷取控制器的類型。</code>
<code> </code><code>// 控制器的類型。</code>
<code> </code><code>public</code> <code>abstract</code> <code>TypeControllerType { </code><code>get</code><code>; }</code>
<code> </code><code>public</code> <code>virtual</code> <code>stringUniqueId { </code><code>get</code><code>; }</code>
<code> </code><code>// 使用指定的名稱和控制器上下文來查找操作方法。</code>
<code> </code><code>// 參數:</code>
<code> </code><code>// controllerContext:</code>
<code> </code><code>// 控制器上下文。</code>
<code> </code><code>// actionName:</code>
<code> </code><code>// 操作的名稱。</code>
<code> </code><code>// 有關操作方法的資訊。</code>
<code> </code><code>public</code> <code>abstract</code> <code>ActionDescriptorFindAction(ControllerContextcontrollerContext, </code><code>string</code> <code>actionName);</code>
<code> </code><code>// 在控制器中檢索操作-方法描述符的清單。</code>
<code> </code><code>// 控制器中的操作-方法描述符的清單。</code>
<code> </code><code>public</code> <code>abstract</code> <code>ActionDescriptor[]GetCanonicalActions();</code>
<code> </code><code>public</code> <code>virtual</code> <code>object</code><code>[]GetCustomAttributes(</code><code>bool</code> <code>inherit);</code>
<code> </code><code>public</code> <code>virtual</code> <code>object</code><code>[]GetCustomAttributes(Type attributeType, </code><code>bool</code> <code>inherit);</code>
<code> </code><code>public</code> <code>virtual</code> <code>boolIsDefined(Type attributeType, </code><code>bool</code> <code>inherit);</code>
<code> </code><code>}</code>
在代碼1-1中,大家也都是看到了ControllerDescriptor類型的定義是抽象類型,其中ControllerName屬性表示着目前控制器上下文中的控制器名稱,ControllerType屬性是被定義為抽象的了,需要在派生類中的實作的(ReflectedControllerDescriptor類型),FindAction()也是抽象的,看這個方法的傳回類型就知道了它是做什麼用的了,對于這部分的細節都是在預設實作類ReflectedControllerDescriptor類型中表示,來看ReflectedControllerDescriptor類型的定義,示例代碼1-2
代碼1-2
<code>public</code> <code>class</code> <code>ReflectedControllerDescriptor : ControllerDescriptor</code>
<code> </code><code>// controllerType:</code>
<code> </code><code>// 異常:</code>
<code> </code><code>// System.ArgumentNullException:</code>
<code> </code><code>// controllerType 參數為 null。</code>
<code> </code><code>publicReflectedControllerDescriptor(TypecontrollerType);</code>
<code> </code><code>public</code> <code>override</code> <code>sealed</code> <code>Type ControllerType { </code><code>get</code><code>;}</code>
<code> </code><code>public</code> <code>override</code> <code>ActionDescriptorFindAction(ControllerContextcontrollerContext, </code><code>string</code> <code>actionName);</code>
<code> </code><code>public</code> <code>override</code> <code>ActionDescriptor[]GetCanonicalActions();</code>
<code> </code><code>public</code> <code>override</code> <code>object</code><code>[]GetCustomAttributes(</code><code>bool</code> <code>inherit);</code>
<code> </code><code>public</code> <code>override</code> <code>object</code><code>[]GetCustomAttributes(Type attributeType, </code><code>bool</code> <code>inherit);</code>
<code> </code><code>public</code> <code>override</code> <code>boolIsDefined(Type attributeType, </code><code>bool</code> <code>inherit);</code>
<code>}</code>
對于ReflectedControllerDescriptor類型的具體實作,在這裡隻是簡要的說明一下,ReflectedControllerDescriptor類型的構造函數參數為Type類型,這裡上面也說過這是Controller類型,在構造函數構造的時候,ReflectedControllerDescriptor類型内部還有個ActionMethodSelector類型的私有變量,ActionMethodSelector類型的構造函數所需參數也是Type類型。這裡為什麼要說到ActionMethodSelector類型呢?因為在ReflectedControllerDescriptor類型的FindAction()方法的具體實作中使用的就是ActionMethodSelector類型中的方法。就如圖1所示的那樣。
本文轉自jinyuan0829 51CTO部落格,原文連結:http://blog.51cto.com/jinyuan/1439207,如需轉載請自行聯系原作者