In the previous introduction we have mentioned that the Modelmetadata object representing the model metadata is ultimately provided through a component named Modelmetadataprovider. Next we focus on the model metadata delivery mechanism based on Modelmetadataprovider and its extension.
First, Modelmetadataprovider
In the ASP.net MVC model metadata-related application programming interface, the Modelmetadataprovider that is used to create the model metadata inherits from the abstract class Modelmetadataprovider. As the following code fragment shows, Modelmetadataprovide has three abstract methods. The Getmetadataforproperties method is used to get a model metadata collection that represents all properties of the specified container object and type. Getmetadataforproperty Gets the model metadata for a specific Property object for the specified container object and type, and Getmetadatafortype returns the model metadata for the container object and type directly.
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:}
Note: The modelmetadataprovider mentioned in this article refer in most cases to direct or indirect inheritance from abstract class Modelmetadataprovider, which is used to provide the provider object or type of model metadata, please note the distinction between readers.
The modelmetadataprovider used in asp.net MVC's metadata parsing system is ultimately obtained by type Modelmetadataproviders. As the following code fragment shows, Modelmetadataproviders has a modelmetadataprovider type of static readable writable property current used to get and set the currently used Modelmetadataprovider.
1:public class Modelmetadataproviders
2: {
3: Public static Modelmetadataprovider current {get; set;}
4:}
Second, Dataannotationsmodelmetadataprovider
We know from the previous introduction that the model metadata is defined by defining the annotation attributes under the System.ComponentModel.DataAnnotations namespace, and the model metadata parsing system is used to solve the annotation characteristics of the data type and its attribute members that are applied in the model. The analysis creates the corresponding initialization of the model metadata, and this work is accomplished by Dataannotationsmodelmetadataprovider.
But Dataannotationsmodelmetadataprovider does not inherit directly from Modelmetadataprovider, but inherits from abstract class Associatedmetadataprovider, The latter is a subclass of Modelmetadataprovider. The main role of Associatedmetadataprovider is to apply the attributes of all "associations" to the model type or attribute, which is also the origin of its naming. As shown in the following code snippet, Associatedmetadataprovider implements the three methods defined in 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:}
For the three methods implemented by Associatedmetadataprovider, it is tightly applied to all attributes on the model type and corresponding properties by reflection. The list of attributes is passed as a parameter (attributes) to the abstract method Createmetadata complete the creation of the model metadata. It is worth mentioning that when a modelmetadata is created by calling Createmetadata, the attributes that implement the Imetadataaware interface are filtered from the list of attributes. and call the Modelmetadata object as a parameter to their onmetadatacreated method.
Inherited from Associatedmetadataprovider Dataannotationsmodelmetadataprovider implements an abstract method that is based on the list of attributes passed in and other relevant information (the delegate that creates the model object, Container and model types and property names implement the final creation of the model metadata. The following code fragment is the definition of the entire dataannotationsmodelmetadataprovider type.
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:}
Included in the model metadata delivery system Modelmetadataprovider, Associatedmetadataprovider, The relationship between Dataannotationsmodelmetadataprovider and Modelmetadataproviders and Modelmetadata can be represented by UML as shown in the following illustration.
Dataannotationsmodelmetadataprovider finally realizes the parsing of model metadata based on annotation feature, However, the type of modelmetadataprovider used by default is not Dataannotationsmodelmetadataprovider, Instead, it cacheddataannotationsmodelmetadataprovider the parsed metadata information into a corresponding ring village to provide performance, In fact, the final implementation of the model metadata is created or dataannotationsmodelmetadataprovider.