ASP.NET Core 啓動過程
- .Net Core 3.1
- VS 2019
創建一個新的ASP.NET Core Web API應用程序
在項目目錄中有兩個關鍵類 Program.cs 和 Startup.cs
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
在Program.cs 的Main函數 調用 CreateHostBuilder 這個方法
CreateHostBuilder 返回一個 IHostBuilder
IHostBuilder 是我們應用程序啓動的核心接口
public interface IHostBuilder
{
IDictionary<object, object> Properties { get; }
IHost Build();
IHostBuilder ConfigureAppConfiguration(Action<HostBuilderContext, IConfigurationBuilder> configureDelegate);
IHostBuilder ConfigureContainer<TContainerBuilder>(Action<HostBuilderContext, TContainerBuilder> configureDelegate);
IHostBuilder ConfigureHostConfiguration(Action<IConfigurationBuilder> configureDelegate);
IHostBuilder ConfigureServices(Action<HostBuilderContext, IServiceCollection> configureDelegate);
IHostBuilder UseServiceProviderFactory<TContainerBuilder>(IServiceProviderFactory<TContainerBuilder> factory);
IHostBuilder UseServiceProviderFactory<TContainerBuilder>(Func<HostBuilderContext, IServiceProviderFactory<TContainerBuilder>> factory);
}
這個接口主要有以上6個方法
我們需要關注的是:
- ConfigureAppConfiguration
- ConfigureHostConfiguration
- ConfigureServices
這三個方法
通過修改Program 和 Startup 來演示啓動過程
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureAppConfiguration(builder => {
Console.WriteLine("ConfigureAppConfiguration");
})
.ConfigureServices(service => {
Console.WriteLine("ConfigureServices");
})
.ConfigureHostConfiguration(builder => {
Console.WriteLine("ConfigureHostConfiguration");
})
.ConfigureWebHostDefaults(webBuilder =>
{
Console.WriteLine("ConfigureWebHostDefaults");
webBuilder.UseStartup<Startup>();
});
修改Startup類
public class Startup
{
public Startup(IConfiguration configuration)
{
Console.WriteLine("Startup");
// snip
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
Console.WriteLine("Startup.ConfigureServices");
// snip
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
Console.WriteLine("Startup.Configure");
// snip
}
}
查看輸出結果
ConfigureWebHostDefaults
ConfigureHostConfiguration
ConfigureAppConfiguration
ConfigureServices
Startup
Startup.ConfigureServices
Startup.Configure
接下來調整一下CreateHostBuilder 中註冊順序
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");
});
然後重新執行查看結果
ConfigureWebHostDefaults
ConfigureHostConfiguration
ConfigureAppConfiguration
Startup
Startup.ConfigureServices
ConfigureServices
Startup.Configure
發現兩次執行的結構有所不同,這個和委託註冊進去的順序有關係,實際上是按照一定的順序執行的;
整個啓動過程分5個階段:
- ConfigureWebHostDefaults: 這個階段註冊了我們應用程序必要的幾個組件,比如配置的組件,容器的組件
- ConfigureHostConfiguration:是用來配置我們應用程序啓動時必要的配置,比如應用程序啓動時需要監聽的端口,URL地址等,在這個過程可以嵌入一些自己配置的類容,注入到配置的框架中
- ConfigureAppConfiguration:用於嵌入自己的配置文件供應用程序讀取,這些配置將會在後續的應用程序執行過程中間每個組件讀取
- ConfigureServices, ConfigureLogging, Startup, Startup.ConfigureServices:都是用來往容器裏面注入我們的應用組件
- Startup.Configure:用來注入中間件,處理 HttpContext 整個請求過程
在整個啓動過程中,Startup 這個類不是必要的.只是這樣讓代碼結構更加合理
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
Console.WriteLine("ConfigureWebHostDefaults");
webBuilder.ConfigureServices(services =>
{
Console.WriteLine("webBuilder.ConfigureServices");
services.AddControllers();
});
webBuilder.Configure(app => {
Console.WriteLine("webBuilder.Configure");
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
});
})
.ConfigureServices(service => {
Console.WriteLine("ConfigureServices");
})
.ConfigureAppConfiguration(builder => {
Console.WriteLine("ConfigureAppConfiguration");
})
.ConfigureHostConfiguration(builder => {
Console.WriteLine("ConfigureHostConfiguration");
});
運行得到的結果
ConfigureWebHostDefaults
ConfigureHostConfiguration
ConfigureAppConfiguration
webBuilder.ConfigureServices
ConfigureServices
webBuilder.Configure
與之前執行的順序也是一致的.
服務註冊一般放在 Startup 的 ConfigureServices,一般是services.AddXXX
中間件的註冊一般放在 Startup 的 Configure 一般是 app.UseXXX