在上篇中,给你们留个对Model元数据的印象,并无对Model元数据有过多的讲解,而在本篇中也不会对Model元数据的自己来解释,而是针对于它的生成过程,让你们可以清楚的了解到系统框架是在何时生成Model元数据的,对于Model元数据生成篇幅初定为两篇,本篇为它的总体的生成过程,下篇则为详细的生成过程而且会对它自己作一个粗略的介绍,但愿你们看完可以有所收获c#
什么是Model元数据?框架
生成Model元数据的过程【一】ide
生成Model元数据的过程【二】spa
ModelMetaData的定义、详解对象
Model元数据应用(经常使用特性应用)-1继承
Model元数据应用(自定义视图模板)-2递归
Model元数据应用(IMetadataAware接口使用)-3接口
仍是如前篇说的那样,既然叫Model元数据(Model指的是视图模型)那么确定跟Model有关系了,而在咱们MVC项目中通常是何时会对Model进行操做呢?通常状况下都是在经过控制器的行为请求一个视图的时候,而控制器行为的参数即为Model,而后在行为方法中作一些处理而后再传递给视图。而后再根据上篇最后的一个示意图来看,ip
图1ci
生成Model元数据的地方已经锁定到了行为方法,想象一下确定是不可能在行为方法中来生成的,由于那是咱们自定义逻辑的地方。那是在什么地方呢?
想必你们看过以前的对过滤器篇幅的介绍,在ASP.NET MVC 过滤器(三)中对行为过滤器的执行过程讲解的时候,中间有提到过模型绑定器,而且说到了系统框架所要使用到的自定义模型绑定器,而使用这个自定义模型绑定器所须要的两个参数是很是重要的,一个是表示当前控制器上下文的对象ControllerContext,另外一个则是生成Model元数据的关键,也是调用自定义模型绑定器的关键参数ModelBindingContext类型。看下
图2
而在ModelBindingContext类型中有个重要的属性,即为Model元数据类型ModelMetadata,由此能够知道在咱们的控制器行为执行以前,对应控制器行为的Model的Model元数据ModelMetadata类型已经生成了。(这部份内容详见过滤器篇幅)
而它是怎么生成的呢?是经过系统框架中默认提供的提供程序来生成的,是哪些个类型呢?
图3
那咱们就先看一下最顶层的基类ModelMetadataProvider的定义:
代码1-1
public abstract class ModelMetadataProvider { // 摘要: // 在派生类中重写时,初始化派生自 System.Web.Mvc.ModelMetadataProvider 类的对象的新实例。 protected ModelMetadataProvider(); public abstract IEnumerable<ModelMetadata> GetMetadataForProperties(object container, Type containerType); public abstract ModelMetadata GetMetadataForProperty(Func<object> modelAccessor, Type containerType, string propertyName); public abstract ModelMetadata GetMetadataForType(Func<object> modelAccessor, Type modelType); }
很是明白的定义,三个抽象方法,这里咱们只需先看GetMetadataForType()方法,其它两个暂时无论下篇中会有讲到,由于先看GetMetadataForType()方法呢?由于它是生成ModelMetadata类型的入口,第一个参数暂时忽略,第二个参数嘛很重要了,是ParameterDescriptor类型的ParameterType属性,表示着Model的类型(也就是控制器方法参数的Type类型),如今咱们来看下图4
图4
图4中蓝色线条为主要流程,红色线条是在蓝色处理以后执行的流程。
上面说到,入口方法是为抽象方法,那是怎么具体实现的呢,从图4中能够看到是由实现了ModelMetadataProvider的类型AssociatedMetadataProvider类型来进行处理的,从图4能够看到首先是获取一个AttributeList的类型,AttributeList类型表示着从AssociatedMetadataProvider类型GetMetadataForType()方法参数modelType类型上的特性集合,对了AssociatedMetadataProvider类型是比较重要的类型,咱们先来看一下它的定义:
public abstract class AssociatedMetadataProvider : ModelMetadataProvider { protected AssociatedMetadataProvider(); protected abstract ModelMetadata CreateMetadata(IEnumerable<Attribute> attributes, Type containerType, Func<object> modelAccessor, Type modelType, string propertyName); protected virtual IEnumerable<Attribute> FilterAttributes(Type containerType, PropertyDescriptor propertyDescriptor, IEnumerable<Attribute> attributes); public override IEnumerable<ModelMetadata> GetMetadataForProperties(object container, Type containerType); protected virtual ModelMetadata GetMetadataForProperty(Func<object> modelAccessor, Type containerType, PropertyDescriptor propertyDescriptor); public override ModelMetadata GetMetadataForProperty(Func<object> modelAccessor, Type containerType, string propertyName); public override ModelMetadata GetMetadataForType(Func<object> modelAccessor, Type modelType); protected virtual ICustomTypeDescriptor GetTypeDescriptor(Type type); }
方法有点多,暂时不用管,大多数方法都是用来在递归生成Model元数据的时候使用的(具体的过程会在下篇中讲解)。好了切回主题接着上面的内容来讲,AttributeList类型的由来,是经过ModelMetadataProvider的GetTypeDescriptor()方法根据Model的类型(这里暂且先这么理解,等看完下个篇幅就会知道这里也有多是Model中的属性类型)来生成一个ICustomTypeDescriptor类型(能够想象成这是对于一种对象类型元数据描述对象的抽象定义。读起来有点绕口,可是确实是这么个意思)。而系统会有个默认的自定义实现来实现这个接口类型,咱们经过这个默认的实现来得到Model类型的AttributeList类型。
在有了AttributeList类型后,咱们就能够调用AssociatedMetadataProvider类型的CreateMetadata()方法来建立Model元数据对象,可是这个CreateMetadata()的定义是抽象的,而真正的实现是由继承了AssociatedMetadataProvider类型的DataAnnotationsModelMetadataProvider类型,由此事后咱们生成获得ModelMetadata元数据对象(真正的过程比较繁琐,否则也不会另起一篇专门用来说解生成的过程),获得了Model元数据对象事后并无结束,而是继续调用了AssociatedMetadataProvider类型的ApplyMetadataAwareAttributes()方法,并在此方法中,系统框架会调用咱们自定义实现了IMetadataAware接口类型的对象,来对Model元数据对象进行个性化修改,而且最后才会真正的返回Model元数据对象。
有可能看到这里有的朋友对Model元数据仍是不怎么清楚和了解,朋友们急我也急,若是我分享的这些知识你们看完都不知所云那我又是何须呢。先不要急看了多少就是多少在看完这个Model元数据系列的文章后应该会有所了解,将在后续的篇章中慢慢的揭开它的秘密。谢谢你们的支持。