HTML5技术

ASP.NET Core MVC 源码学习:MVC 启动流程详解 - Savorboard(2)

字号+ 作者:H5之家 来源:H5之家 2017-03-27 18:01 我要评论( )

在 AddRazorViewEngine 中,又一次执行了 builder.AddViews() ,不知道这个是 Bug 还是故意这样的, 我猜测有可能是一些地方单独使用视图引擎做一些操作,而 AddRazorViewEngine 又依赖于 AddViews 中提供的一些服

在 AddRazorViewEngine 中,又一次执行了 builder.AddViews() ,不知道这个是 Bug 还是故意这样的, 我猜测有可能是一些地方单独使用视图引擎做一些操作,而 AddRazorViewEngine 又依赖于 AddViews 中提供的一些服务,所以又重新执行了 AddView()。

经过 github 的 issue 印证,这并不是 bug,而是设计如此。开发团队在实现这一块的功能的时候,AddXXX 的 设计策略就是会自动添加依赖的服务,因为这样比较更加友好,这种形式对于添加什么服务也更加的明确。 当然他们也讲到,将很多的碎片服务再进行碎片的细分是非常复杂的,有时候会有点不切实际,所以此处不得不如此。

接下来,又向 ApplicationPartMangager 里面的 FeatureProviders 添加了 TagHelperFeatureProvider,MetadataReferenceFeatureProvider,ViewsFeatureProvider 的实例。

AddRazorPages

处理Razor Pages 中的一些业务操作,在 AddRazorPages 中,又一次调用了 AddRazorViewEngine() ,而 AddRazorViewEngine 里面又调用了 AddView() ,又此可见这些组件都是环环相扣的,他们都有自己的机制来确保服务的健全。

AddCacheTagHelper

添加 MVC Cache Tag Helper 服务。

在这个注册的服务中,有两个关于缓存的服务,一个是 IDistributedCache 另外一个是 IMemoryCache,当你主动注册一个IDistributedCache的时候,将会使用你注册的IDistributedCache。

AddDataAnnotations

注册了以下两个服务,我就不画图了。

  • MvcDataAnnotationsMvcOptionsSetup
  • IValidationAttributeAdapterProvider
  • 处理 Mvc Model 中数据注解相关业务,第一个 MvcDataAnnotationsMvcOptionsSetup 将会在 MvcOptions 的 ModelMetadataDetailsProviders 属性中添加 DataAnnotationsMetadataProvider 和 DataAnnotationsModelValidatorProvider

    MvcDataAnnotationsMvcOptionsSetup 实现了 IConfigureOptions<MvcOptions>, 下面是它的 Configure 方法。

    public void Configure(MvcOptions options) { if (options == null) { throw new ArgumentNullException(nameof(options)); } options.ModelMetadataDetailsProviders.Add(new DataAnnotationsMetadataProvider( _dataAnnotationLocalizationOptions, _stringLocalizerFactory)); options.ModelValidatorProviders.Add(new DataAnnotationsModelValidatorProvider( _validationAttributeAdapterProvider, _dataAnnotationLocalizationOptions, _stringLocalizerFactory)); } AddJsonFormatterServices

    关于MVC 输入 Json 格式化的配置项,还有 JsonResultExecutor。 以及 JsonPatch 的相关操作。

    有些同学可能对 JsonPatch 不太了解,那么 JsonPatch 是什么东西呢?
    JSON Patch 在 IETF 中规范是 RFC 6902。
    JSON Patch 是一个用来描述 JSON 文档变化的格式,它本身也是 JSON 文档。它可以用于避免在只有一个节点更改时发送整个文档。当与HTTP PATCH方法组合使用时,它允许以符合标准的方式对HTTP API进行部分更新。例如:

    源文件:

    { "baz": "qux", "foo": "bar" }

    Patch:

    [ { "op": "replace", "path": "/baz", "value": "boo" }, { "op": "add", "path": "/hello", "value": ["world"] }, { "op": "remove", "path": "/foo" ]

    结果:

    { "baz": "boo", "hello": ["world"] }

    那么 ASP.NET Core 中,微软对 RFC 6902 协议的实现位于 Microsoft.AspNetCore.JsonPatch 这个 NuGet 包里面。

    MVC 框架针对于 Json Patch 提供了一扩展方法 JsonPatchExtensions,需要的同学自行使用。

    AddCors
  • IApplicationModelProvider , CorsApplicationModelProvider
  • CorsAuthorizationFilter
  • 下面是 CorsApplicationModelProvider 执行的时候的代码,就是向 ControllerModel 中添加 Filter:

    public void OnProvidersExecuting(ApplicationModelProviderContext context) { IEnableCorsAttribute enableCors; IDisableCorsAttribute disableCors; foreach (var controllerModel in context.Result.Controllers) { enableCors = controllerModel.Attributes.OfType<IEnableCorsAttribute>().FirstOrDefault(); if (enableCors != null) { controllerModel.Filters.Add(new CorsAuthorizationFilterFactory(enableCors.PolicyName)); } disableCors = controllerModel.Attributes.OfType<IDisableCorsAttribute>().FirstOrDefault(); if (disableCors != null) { controllerModel.Filters.Add(new DisableCorsAuthorizationFilter()); } foreach (var actionModel in controllerModel.Actions) { enableCors = actionModel.Attributes.OfType<IEnableCorsAttribute>().FirstOrDefault(); if (enableCors != null) { actionModel.Filters.Add(new CorsAuthorizationFilterFactory(enableCors.PolicyName)); } disableCors = actionModel.Attributes.OfType<IDisableCorsAttribute>().FirstOrDefault(); if (disableCors != null) { actionModel.Filters.Add(new DisableCorsAuthorizationFilter()); } } } }

    其中 CorsAuthorizationFilterFactory 的实例会创建 CorsAuthorizationFilter 。 有关 Cors 的更多示例可以看这里。

    UseMvc

    UseMvc 的主要过程是Router中间件的初始化和启动过程,关于Router中间件可以看一下我的上一篇文章,执行流程如下:

    1、构建 middlewarePipelineBuilder,它是一个新的 ApplicationBuilder 实例。

    2、在UseMvc中,主要是应用 Router 中间件,进行路由拦截。

    3、构建 RouterBuilder , 添加或配置 IRouteBuilder。

    4、使用IRouteBuilder 注册 Router 中间件。

    总结

     

    1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

    相关文章
    • 车大棒浅谈jQuery源码(一) - 车大棒

      车大棒浅谈jQuery源码(一) - 车大棒

      2017-03-27 09:00

    • vue2源码浏览分析01 - 小结巴巴吧

      vue2源码浏览分析01 - 小结巴巴吧

      2017-03-21 09:00

    • 人工智能火爆,我的研究更劲爆——开启全民窃听风云——智能窃听程序源码放送! - 熬夜与烟

      人工智能火爆,我的研究更劲爆——开启全民窃听风云——智能窃听程序

      2017-03-14 16:01

    • 一份关于组建.NET Core开源团队的倡议书 - 彭泽0902

      一份关于组建.NET Core开源团队的倡议书 - 彭泽0902

      2017-03-13 17:02

    网友点评
    /