前言
在 上一篇 文章中,我们学习了 ASP.NET Core MVC 的路由模块,那么在本篇文章中,主要是对 ASP.NET Core MVC 启动流程的一个学习。
ASP.NET Core 是新一代的 ASP.NET 应用程序,它是跨平台的,并且不依赖于 IIS,新的 MVC Core 设计加入了依赖注入和模块化的 Http 处理管道,这篇文章我们一起通过源码看一下它的启动过程,每一步都很重要。
我们知道 MVC Core 是作为一个中间件程序,注册到 ASP.NET Core 管道流程中的,我先来回顾一下在以前基于 IIS 的传统 ASP.NET 程序。 传统的 ASP.NET 应用程序由可执行文件 InetMgr.exe (IIS 宿主进程)创建,然后调用受托管的应用程序入口,接着调用 HttpApplication.Application_Start()
进一步初始化,通常情况下,我们的初始化代码都写在 Application_StartGlobal.asax
中。
我们今天的主题是MVC 框架,所以针对 ASP.NET Core Host 和 Server 的初始化流程就不详细讲解了,由兴趣的同学可以翻看一下我的这篇文章。
ASP.NET Core 源码地址:https://github.com/aspnet/mvc
Getting Started
ASP.NET Core MVC 源码程序主要包含几部分组成:
Mvc.Core :源码的核心实现,包含认证,过滤,模型绑定,路由等等...
Mvc.Razor:Razor视图的拓展实现,模板引擎等,核心实现在Rozor那个项目。
Mvc.TagHelper:Razor中 TagHelper的主要实现。
Mvc.ViewFeatures:Razor中视图组件的渲染等。
从 Startup 说起
ASP.NET Core MVC 程序在启动之后,会经过一系列流程,然后到达 Microsoft.AspNetCore.Mvc包里的扩展程序 IMvcBuilder AddMvc(this IServiceCollection services)
中,然后我们从 ConfigureServices
这个分支说起吧。
在 Startup
启动的时候,会在 ConfigureServices
中注册 AddMvc 的 DI 服务,那么MVC也是在这个时候注入到DI容器中的,在MVC中所有的注入都是使用 TryAddXXX
的形式,也就是如果容器中已经有相关服务的话,将不会添加新注册的服务,所以如果你有一些服务需要进行重写的话,需要在 builder.AddMvc()
之前注册到DI中。
我们先看一下 AddMvc 的返回值 IMvcBuilder
, IMvcBuilder
是一个针对 IServiceCollection 包装的一个接口,除了IServiceCollection之外,还有一个 ApplicationPartManager
。那么它是干嘛的呢?
从命名来看 ApplicationPartManager
是用来管理 ApplicationPart
的,那么其实除了里面 ApplicationPart 之外还有 IApplicationFeatureProvider
。
public interface IMvcBuilder{
IServiceCollection Services { get; }
ApplicationPartManager PartManager { get; }
}
ApplicationPart
它是 MVC Core 中引用的一个抽象的概念,它允许你暴露一些特性或者一些已知的资源,比如一些元数据信息,发布的资源,磁盘的文件等。
你可以在应用程序启动的时候进行 ApplicationPart
的配置,它是作为 IMvcBuilder
扩展的一部分。
目前 MVC 框架针对 ApplicationPart 的默认实现只有 AssemblyPart,当然你可以根据需要进行扩展。
ApplicationPartManager
private static void AddDefaultFrameworkParts(ApplicationPartManager partManager){
var mvcTagHelpersAssembly = typeof