ASP.NET MVC的Model中繼資料提供機制的實現

來源:互聯網
上載者:User

在前面的介紹中我們已經提到過表示Model中繼資料的ModelMetadata對象最終是通過一個名為ModelMetadataProvider的組件提供的,接下來我們著重討論基於ModelMetadataProvider的Model中繼資料提供機制及其擴充。

一、 ModelMetadataProvider

在ASP.NET MVC的Model中繼資料相關的應用編程介面中,用於建立Model中繼資料的ModelMetadataProvider接繼承自抽象類別ModelMetadataProvider。如下面的代碼片斷所示,ModelMetadataProvide具有三個抽象方法。GetMetadataForProperties方法用於擷取表示針對指定容器物件和類型所有屬性的Model中繼資料集合,GetMetadataForProperty擷取針對指定容器物件和類型某個具體屬性對象的Model中繼資料,而GetMetadataForType則直接返回針對容器物件和類型的Model中繼資料。

   1: public abstract class ModelMetadataProvider
2: {
3: public abstract IEnumerable<ModelMetadata> GetMetadataForProperties( object container, Type containerType);
4: public abstract ModelMetadata GetMetadataForProperty(Func<object> modelAccessor, Type containerType, string propertyName);
5: public abstract ModelMetadata GetMetadataForType(Func<object> modelAccessor, Type modelType);
6: }

註:在本文中提及的ModelMetadataProvider在大部分情況泛指直接或者間接繼承自抽象類別ModelMetadataProvider,用於提供Model中繼資料的提供者對象或者類型,請讀者注意區分。

在ASP.NET MVC的中繼資料解析系統中使用的ModelMetadataProvider最終通過類型ModelMetadataProviders擷取。如下面的代碼片斷所示,ModelMetadataProviders具有一個ModelMetadataProvider類型的靜態可讀可寫屬性Current用於擷取和設定當前使用的ModelMetadataProvider。

   1: public class ModelMetadataProviders
2: {
3: public static ModelMetadataProvider Current { get; set; }
4: }

二、DataAnnotationsModelMetadataProvider

通過前面的介紹我們知道Model中繼資料是通過定義在System.ComponentModel.DataAnnotations命名空間下的標註特性來定義的,Model中繼資料解析系統通過對應用在表示Model的資料類型及其屬性成員的標註特性進行解析從而對建立的Model中繼資料進行對應的初始化,而這個工作是通過DataAnnotationsModelMetadataProvider來實現的。

不過DataAnnotationsModelMetadataProvider並沒有直接繼承自ModelMetadataProvider,而是繼承自抽象類別AssociatedMetadataProvider,後者是ModelMetadataProvider的子類。AssociatedMetadataProvider的主要作用是對應用在Model類型或屬性上所有“關聯”的特性,這也是它命名的由來。如下面的代碼片斷所示,AssociatedMetadataProvider實現了定義在ModelMetadataProvider的三個方法。

   1: public abstract class AssociatedMetadataProvider : ModelMetadataProvider
2: {
3: protected abstract ModelMetadata CreateMetadata(IEnumerable<Attribute> attributes, Type containerType, Func<object> modelAccessor, Type modelType, string propertyName);
4:
5: public override IEnumerable<ModelMetadata> GetMetadataForProperties(object container, Type containerType);
6: public override ModelMetadata GetMetadataForProperty(Func<object> modelAccessor, Type containerType, string propertyName);
7: public override ModelMetadata GetMetadataForType(Func<object> modelAccessor, Type modelType);
8: }

對於AssociatedMetadataProvider實現的三個方法,它並緊緊是通過反射將應用在Model類型和對應屬性上的所有特性,並將這個特性列表作為參數(attributes)傳入抽象方法CreateMetadata完成Model中繼資料的建立。值得一提的是,當通過調用CreateMetadata建立出ModelMetadata之後,會從特性列表中篩選出實現了IMetadataAware介面的特性,並將該ModelMetadata對象作為參數調用它們的OnMetadataCreated方法。

繼承自AssociatedMetadataProvider的DataAnnotationsModelMetadataProvider實現了抽象方法,它根據傳入的特性列表以及其他相關的資訊(用於建立Model對象的委託、容器和Model類型以及屬性名稱)實現對Model中繼資料的最終建立。下面的代碼片斷就是整個DataAnnotationsModelMetadataProvider類型的定義。

   1: public class DataAnnotationsModelMetadataProvider : AssociatedMetadataProvider
2: {
3: public DataAnnotationsModelMetadataProvider();
4: protected override ModelMetadata CreateMetadata(IEnumerable<Attribute> attributes, Type containerType,
5: Func<object> modelAccessor, Type modelType, string propertyName);
6: }

包含在Model中繼資料提供系統的ModelMetadataProvider、AssociatedMetadataProvider、DataAnnotationsModelMetadataProvider和ModelMetadataProviders與ModelMetadata之間的關係可以通過如下圖所示的UML來體現。

DataAnnotationsModelMetadataProvider最終實現了基於標註特性的Model中繼資料的解析,但是在預設情況下使用的ModelMetadataProvider類型卻不是DataAnnotationsModelMetadataProvider,而是CachedDataAnnotationsModelMetadataProvider,它對解析出來的中繼資料資訊進行了相應的環村以提供效能,其實最終實現對Model中繼資料建立的還是DataAnnotationsModelMetadataProvider。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.