在 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注册了以下两个服务,我就不画图了。
处理 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下面是 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 的更多示例可以看这里。
UseMvcUseMvc 的主要过程是Router中间件的初始化和启动过程,关于Router中间件可以看一下我的上一篇文章,执行流程如下:
1、构建 middlewarePipelineBuilder,它是一个新的 ApplicationBuilder 实例。
2、在UseMvc中,主要是应用 Router 中间件,进行路由拦截。
3、构建 RouterBuilder , 添加或配置 IRouteBuilder。
4、使用IRouteBuilder 注册 Router 中间件。
总结