ASP.NET Core知多少系列:总体介绍及目录

1. 引言

对于ASP.NET Core应用程序来说,我们要记住非常重要的一点是:其本质上是一个独立的控制台应用,它并不是必需在IIS内部托管且并不需要IIS来启动运行(而这正是ASP.NET Core跨平台的基石)。ASP.NET Core应用程序拥有一个内置的Self-Hosted(自托管)Web Server(Web服务器),用来处理外部请求。

不管是托管还是自托管,都离不开Host(宿主)。在ASP.NET Core应用中通过配置并启动一个Host来完成应用程序的启动和其生命周期的管理(如下图所示)。而Host的主要的职责就是Web Server的配置和Pilpeline(请求处理管道)的构建。

这张图描述了一个总体的启动流程,从上图中我们知道ASP.NET Core应用程序的启动主要包含三个步骤:

  1. CreateDefaultBuilder():创建IWebHostBuilder
  2. Build():IWebHostBuilder负责创建IWebHost
  3. Run():启动IWebHost

所以,ASP.NET Core应用的启动本质上是启动作为宿主的WebHost对象。

其主要涉及到两个关键对象IWebHostBuilderIWebHost,它们的内部实现是ASP.NET Core应用的核心所在。下面我们就结合源码并梳理调用堆栈来一探究竟!

2. 宿主构造器:IWebHostBuilder

在启动IWebHost宿主之前,我们需要完成对IWebHost的创建和配置。而这一项工作需要借助IWebHostBuilder对象来完成的,ASP.NET Core中提供了默认实现WebHostBuilder。而WebHostBuilder是由WebHost的同名工具类(Microsoft.AspNetCore命名空间下)中的CreateDefaultBuilder方法创建的。

从上图中我们可以看出CreateDefaultBuilder()方法主要干了六件大事:

  1. UseKestrel:使用Kestrel作为Web server。
  2. UseContentRoot:指定Web host使用的content root(内容根目录),比如Views。默认为当前应用程序根目录。
  3. ConfigureAppConfiguration:设置当前应用程序配置。主要是读取 appsettinggs.json 配置文件、开发环境中配置的UserSecrets、添加环境变量和命令行参数 。
  4. ConfigureLogging:读取配置文件中的Logging节点,配置日志系统。
  5. UseIISIntegration:使用IISIntegration 中间件。
  6. UseDefaultServiceProvider:设置默认的依赖注入容器。

创建完毕WebHostBuilder后,通过调用UseStartup()来指定启动类,来为后续服务的注册及中间件的注册提供入口。

3. 宿主:IWebHost

在ASP.Net Core中定义了IWebHost用来表示Web应用的宿主,并提供了一个默认实现WebHost。宿主的创建是通过调用IWebHostBuilderBuild()方法来完成的。那该方法主要做了哪些事情呢,我们来看下面这张【ASP.NET Core启动流程调用堆栈】中的黄色边框部分:

其核心主要在于WebHost的创建,又可以划分为三个部分:

  1. 构建依赖注入容器,初始通用服务的注册:BuildCommonService();
  2. 实例化WebHost:var host = new WebHost(...);
  3. 初始化WebHost,也就是构建由中间件组成的请求处理管道:host.Initialize();

3.1. 注册初始通用服务

BuildBuildCommonService方法主要做了两件事:

  1. 查找HostingStartupAttribute特性以应用其他程序集中的启动配置
  2. 注册通用服务
  3. 若配置了启动程序集,则发现并以IStartup类型注入到IOC容器中

3.2. 创建IWebHost

public IWebHost Build()
{
//省略部分代码 var host = new WebHost(
applicationServices,
hostingServiceProvider,
_options,
_config,
hostingStartupErrors);
} host.Initialize(); return host;
}

3.3. 构建请求处理管道

请求管道的构建,主要是中间件之间的衔接处理。

而请求处理管道的构建,又包含三个主要部分:

  1. 注册Startup中绑定的服务;
  2. 配置IServer;
  3. 构建管道

请求管道的构建主要是借助于IApplicationBuilder,相关类图如下:

4. 启动WebHost

WebHost的启动主要分为两步:

  1. 再次确认请求管道正确创建
  2. 启动Server以监听请求
  3. 启动 HostedService

4.1. 确认请求管道的创建

从图中可以看出,第一步调用Initialize()方法主要是取保请求管道的正确创建。其内部主要是对BuildApplication()方法的调用,与我们上面所讲WebHost的构建环节具有相同的调用堆栈。而最终返回的正是由中间件衔接而成的RequestDelegate类型代表的请求管道。

4.2. 启动Server

我们先来看下类图:

从类图中我们可以看出IServer接口主要定义了一个只读的特性集合属性、一个启动和停止的方法声明。在创建宿主构造器IWebHostBuilder时我们通过调用UseKestrel()方法指定了使用KestrelServer作为默认的IServer实现。其方法申明中接收了一个IHttpApplication<TContext> application的参数,从命名来看,它代表一个Http应用程序,我们来看下具体的接口定义:

其主要定义了三个方法,第一个方法用来创建请求上下文;第二个方法用来处理请求;第三个方法用来释放上下文。而至于请求上下文,是用来携带请求和返回响应的核心参数,其贯穿与整个请求处理管道之中。ASP.NET Core中提供了默认的实现HostingApplication,其构造函数接收一个RequestDelegate _application(也就是链接中间件形成的处理管道)用来处理请求。

var httpContextFactory = _applicationServices.GetRequiredService<IHttpContextFactory>();
var hostingApp = new HostingApplication(_application, _logger, diagnosticSource, httpContextFactory);

4.3. 启动IHostedService

IHostedService接口用来定义后台任务,通过实现该接口并注册到Ioc容器中,它会随着ASP.NET Core 程序启动而启动,终止而终止。

5. 总结

结合源码,通过对ASP.NET Core运行调用堆栈的梳理,其启动流程的总体脉络一目了然,并且了解到主要的几个关键对象:

  1. 负责创建IWebHost的宿主构造器IWebHostBuilder
  2. 代表宿主的IWebHost接口
  3. 用于构建请求管道的IApplicationBuilder
  4. 中间件衔接而成的RequestDelegate
  5. 代表Web Server的IServer接口
  6. 贯穿请求处理管道的请求上下文HttpContext
  7. 可以用来注册后台服务的IHostedService接口

本文经「原本」原创认证,作者圣杰,访问yuanben.io查询【E5OW396N】获取授权信息。

一张图理清ASP.NET Core启动流程的更多相关文章

  1. ASP.NET Core启动流程

    1. 引言 对于ASP.NET Core应用程序来说,我们要记住非常重要的一点是:其本质上是一个独立的控制台应用,它并不是必需在IIS内部托管且并不需要IIS来启动运行(而这正是ASP.NET Cor ...

  2. Asp.net Core 启动流程分析

    新建的.net core 程序启动本质上是一个控制台应用程序,所以它的入口在Main方法中,所以启动的开始时从Main方法开始. public class Program { public stati ...

  3. Asp.net Core启动流程讲解(四)

    Asp.net Core内 DI(DependencyInjection)贯穿了项目的始终,要学习Asp.net Core就无法越过DI. 下面讲解一下DI在Asp.Net Core内的流程 asp. ...

  4. Asp.net core 启动流程

  5. 产品经理-需求分析-用户故事-敏捷开发 详解 一张图帮你了解Scrum敏捷流程

    产品经理-需求分析-用户故事-敏捷开发 详解 用户故事是从用户的角度来描述用户渴望得到的功能.一个好的用户故事包括三个要素:1. 角色:谁要使用这个功能.2. 活动:需要完成什么样的功能.3. 商业价 ...

  6. ASP.NET CORE 启动过程及源码解读

    在这个特殊的春节,大家想必都在家出不了们,远看已经到了回城里上班的日子,但是因为一只蝙蝠的原因导致我们无法回到工作岗位,大家可能有的在家远程办公,有些在家躺着看书,有的是在家打游戏:在这个特殊无聊的日 ...

  7. asp.net core启动源码以及监听,到处理请求响应的过程

    摘要 asp.net core发布至今已经将近6年了,很多人对于这一块还是有些陌生,或者说没接触过:接触过的,对于asp.net core整个启动过程,监听过程,以及请求过程,响应过程也是一知半解,可 ...

  8. 一张图理清 Python3 所有知识点

    如果你前几天一直有关注 GitHub Trending,那你应该会留意到「Python3 in one pic」这个开源项目. 很多人学习python,不知道从何学起.很多人学习python,掌握了基 ...

  9. 聊聊asp.net core 授权流程

    在上一篇 聊聊 asp.net core 认证和授权 中我们提到了认证和授权的基本概念,以及认证和授权的关系及他们之间的协同工作流程,在这篇文章中,我将通过分析asp.net core 3.1 授权流 ...

随机推荐

  1. 根据本周本月本日来查询数据 C#winform数据查询

    这个我是在winform的页面上做的 1. 首先是在页面上添加3个lable   第一次点击lable会有相应的数据被查询出来  第二次点击同一个lable会刷新所有的数据 2.点击不同的label会 ...

  2. mysql 索引B-Tree类型对索引使用的生效和失效情况详解

    详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt343 当人们谈论索引的时候,如果没有特别指明类型 ,那多半说的是 B-Tre ...

  3. WebApi Ajax 跨域请求解决方法(CORS实现)(作者:jianxuanbing)

    概述 ASP.NET Web API 的好用使用过的都知道,没有复杂的配置文件,一个简单的ApiController加上需要的Action就能工作.但是在使用API的时候总会遇到跨域请求的问题,特别各 ...

  4. springboot 入门一 hello world!

    微服务框架springboot,目的是用来简化新Spring应用的初始搭建以及开发过程.简化的代价,就是约定俗成很多规则,比如默认读取的配置文件名是application.properties 必需在 ...

  5. poj 2553 强连通

    题意:给出一个有向图,定义:若节点v所有能到达的点{wi},都能反过来到达v,那么称节点v是sink.题目要求所有的sink点. 思路:强连通缩点找出出度为零的点,输出即可. 这题主要问题是读题,了解 ...

  6. Spring MVC入门讲解

    一.Springmvc是什么? Spring Web MVC是一种基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架,即使用了MVC架构模式的思想, 将web层进行职责解耦,基 ...

  7. unity3D HTC VIVE开发-物体高亮功能实现

    在VR开发时,有时需要用到物体高亮的功能.这里使用Highlighting System v3.0.1.unitypackage插件实现. Highlighting System v3.0.1的介绍访 ...

  8. 201521123089 《Java程序设计》第5周学习总结

    1. 本周学习总结 1.1 尝试使用思维导图总结有关多态与接口的知识点. 2. 书面作业 1.代码阅读:Child压缩包内源代码1.1 com.parent包中Child.java文件能否编译通过?哪 ...

  9. 学号:201521123116 《java程序设计》第一周学习总结

    #1. 本章学习总结了解了班级的纪律和期末成绩组成.本周重点学习了java语言的特点具有简单性和结构中立.明白了jdk是java开发人员使用的一种工具,以及编写一个java程序的所需步骤,懂得了jdk ...

  10. 201521123106 《Java程序设计》第13周学习总结

    1. 本周学习总结 以你喜欢的方式(思维导图.OneNote或其他)归纳总结多网络相关内容. 2. 书面作业 1. 网络基础 1.1 比较ping www.baidu.com与ping cec.jmu ...