ASP.NET Core (Hosting)

ASP.NET Core 应用本质上就是长时间运行的服务,该服务接受一个 HTTP 请求,然后按照预先设计好的路由规则,返回对应的响应(response)。一个 ASP.NET Core 应用程序包含两个主要的组件。

  • Server (接受和响应请求)
  • Middleware (处理请求的中间件)

在这篇文章中,将会通过阅读 ASP.NET Core 源码的方式,来探索 ASP.NET Core 如何将服务注册到 Host 中的。

1. Overview

IHostBuilder 通过建造者模式创建一个 IHost 对象,在执行 Run 方法的时候,会从依赖注册容器中获取所有的 IHostedService 服务,然后依次启动它们。在 ASP.NET Core 框架中,我们将会把 GenericWebHostService 注册到容器中。

下面就是最简单的 ASP.NET Core 应用程序

  1. Host.CreateDefaultBuilder 方法创建一个 IHostBuilder 的对象
  2. ConfigureWebHostDefaultsIHostBuilder 的拓展方法,主要是调用 ConfigureWebHost 方法,其中调用了 WebHost 的静态方法 ConfigureWebDefaults
public static IHostBuilder ConfigureWebHostDefaults(this IHostBuilder builder, Action <IWebHostBuilder> configure) {
if (configure is null) {
throw new ArgumentNullException(nameof(configure));
}
return builder.ConfigureWebHost(webHostBuilder => {
WebHost.ConfigureWebDefaults(webHostBuilder);
configure(webHostBuilder);
});
}

3. WebHost.ConfigureWebDefaults 开始往服务注入相关服务

4. ConfigWebHost 开始注册 IHostedSerivce 对象 GenericWebHostService

5. Run 方法通过 IApplicationBuilder 注册了一个中间件

2. GenericWebHostService

3. GenericWebHostBuilder

3.1 构造函数

  • 使用这个对象构建 Host 的配置信息
  • 配置Host Application 的配置
  • 接下来是往 builder 中的依赖注入服务, 包括 IWebHostEnvironmentIApplicationLifeTime , 添加 GenericWebHostSeriveOptions Option 选项,添加 DiagnosticListenerDiagnosticSource ; IHttpContextFactoryDefaultHttpContextFactory 提供服务; IMiddlewareFactory 服务由 MiddlewareFactory 服务提供; IApplicationBuilderFactoryApplicationBuilderFactory 服务提供
  • 如果选项中添加了 Startup 的的程序集,需要加载进来。

3.2 ConfigureAppConfiguration

3.3 ConfigureService

3.4 UseStartup

// UseStartup can be called multiple times. Only run the last one._startupObject = startupType;_builder.ConfigureServices((context, services) =>{// Run this delegate if the startup type matches
if (object.ReferenceEquals(_startupObject, startupType)){
UseStartup(startupType, context, services); }});return this;

那么真正调用的 UseStartup 方法都干了什么事情呢?

  • 首选判断这个 Startup 这个类是否支持,如果类是实现 IStartup 接口是不支持的,如果 ConfigureService 方法返回 IServiceProvider 也是不支持的,
  • 然后创建一个 Startup 的实例,但是要注意的是,它支持构造函数只包含 IHostingEnvironment,IWebHostEnvironment, IHostEnvironment, IConfiguration 这些参数的 StartUp 类型
  • 然后执行 ConfigServcie 这个方法,要注意这个方法名字可以是 ConfigService 或者 Config{Environment}Name
  • 然后然后获取 Configure 方法,然后更新 GenericWebHostServiceOptions 中的 ConfiguApplication 方法,将 Configure 方法中的注册的中间件添加到其中。

3.5 Configure 方法

4 GenericWebHostSerivce

  • 设置接受请求的地址,如果该服务可以配置请求地址,则从配置文件中,将地址添加到服务中。
  • options 中的请求获取所有注册的 Action<IApplicationBuilder> ,也就是中间件,然后通过 ApplicationBuilderFactory 构建一个 IApplicaitonBuilder 对象,然后通过 build 方法,构建出一个 RequestDelegate 对象
  • 获取到对象后,创建一个 HostingApplication 对象,然后调用 ServerStartAsync 方法来启动整个服务。

A software developer in Microsoft at Suzhou. Most articles spoken language is Chinese. I will try with English when I’m ready

A software developer in Microsoft at Suzhou. Most articles spoken language is Chinese. I will try with English when I’m ready