.NET Core开发实战课程备忘(1) -- ASP.NET Core的启动流程

课程目标

主要是掌握ASP.NET Core应用程序启动的流程,同时了解启动过程中哪些方法做了哪些操作

创建项目

创建ASP.NET Core Web项目,项目类型选择API,直接创建即可

添加日志代码

本实例不涉及任何业务代码,纯粹只是添加日志查看各个方法的调用流程

修改Program.cs,以下直接放修改后的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
using System;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;

namespace StartupDemo
{
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}

public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
Console.WriteLine("ConfigureWebHostDefaults");
webBuilder.UseStartup<Startup>();
})
.ConfigureServices(service =>
{
Console.WriteLine("ConfigureServices");
})
.ConfigureAppConfiguration(builder =>
{
Console.WriteLine("ConfigureAppConfiguration");
})
.ConfigureHostConfiguration(builder =>
{
Console.WriteLine("ConfigureHostConfiguration");
});
}
}

修改Startup.cs,以下直接放修改后的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
using System;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

namespace StartupDemo
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Console.WriteLine("Startup.Ctor");
Configuration = configuration;
}

public IConfiguration Configuration { get; }

public void ConfigureServices(IServiceCollection services)
{
Console.WriteLine("Startup.ConfigureServices");
services.AddControllers();
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
Console.WriteLine("Startup.Configure");
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}

app.UseHttpsRedirection();

app.UseRouting();

app.UseAuthorization();

app.UseStaticFiles();

app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
}

运行结果

参照上面将代码修改完,直接运行代码,控制台将打印出以下信息

1
2
3
4
5
6
7
ConfigureWebHostDefaults
ConfigureHostConfiguration
ConfigureAppConfiguration
Startup.Ctor
Startup.ConfigureServices
ConfigureServices
Startup.Configure

结论

以下为ASP.NET Core启动运行流程

  • ConfigureWebHostDefaults:注册了应用程序必要的几个组件,比如说配置的组件、容器的组件等
  • ConfigureHostConfiguration:配置程序启动时必要的配置,比如说程序启动时所需要监听的端口、需要监听的URL地址等,在这个过程可以嵌入我们自己的配置内容注入到配置的框架中去
  • ConfigureAppConfiguration:嵌入我们自己的配置文件,供应用程序来读取,这些配置将来会在后续的应用程序执行过程中每个组件读取
  • ConfigureServices/ConfigureLogging/Startup/Startup.ConfigureServices:这些都是往容器里面来注入我们的应用的组件
  • Startup.Configure:注入中间件,处理HttpContext整个的请求过程

另外

从代码运行来看,Startup.cs这个类可以被整合到Program.cs里的ConfigureWebHostDefaults方法中,
可以直接ConfigureWebHostDefaults方法中直接使用webBuilder调用ConfigureServicesConfigure两个方法
具体可以参考以下代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
using System;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

namespace StartupDemo
{
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}

public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
Console.WriteLine("ConfigureWebHostDefaults");
webBuilder.ConfigureServices(services =>
{
Console.WriteLine("Program.ConfigureServices");
services.AddControllers();
});
webBuilder.Configure(app =>
{
Console.WriteLine("Program.Configure");
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseStaticFiles();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
});
})
.ConfigureServices(service =>
{
Console.WriteLine("ConfigureServices");
})
.ConfigureAppConfiguration(builder =>
{
Console.WriteLine("ConfigureAppConfiguration");
})
.ConfigureHostConfiguration(builder =>
{
Console.WriteLine("ConfigureHostConfiguration");
});
}
}

但是为了代码结构更加合理,还是需要用Startup这个类来分离变动比较大的代码

通常是在Startup.ConfigureServices的方法里做服务注册,一般是Addxxx

在Startup.Configure决定注册那些中间件到处理过程中去