04 | Startup:掌握ASP.NET Core的啟動過程
新建一個 ASP.NET Core Web 應用程序
選擇 API
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 方法返回了一個 IHostBuilder
它是應用程序啟動的核心接口
IHostBuilder 接口有六個方法:
主要關注以下三個:
- ConfigureAppConfiguration
- ConfigureHostConfiguration
- ConfigureServices
接下來,我們添加一些代碼演示整個應用程序的啟動過程:
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 Startup(IConfiguration configuration)
{
Console.WriteLine("Startup");
...
public void ConfigureServices(IServiceCollection services)
{
Console.WriteLine("ConfigureServices");
...
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
Console.WriteLine("Configure");
...
啟動程序查看輸出:
ConfigureWebHostDefaults
ConfigureHostConfiguration
ConfigureAppConfiguration
ConfigureServices
Startup
Startup.ConfigureServices
Startup.Configure
調整一下委托的注冊順序
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
本質上,如果查看源碼會發現,委托注冊進去之后,實際上是按照一定的順序來執行的:
1、ConfigureWebHostDefaults
這個階段注冊了應用程序必要的幾個組件,比如配置的組件、容器組件
2、ConfigureHostConfiguration
用於配置應用程序啟動時必要的配置,比如應用程序啟動時所需要監聽的端口,URL 地址
在這個過程可以嵌入一些自己配置的內容,注入到配置的框架中
3、ConfigureAppConfiguration
用於嵌入自己的配置文件,供應用程序讀取,這些配置將會在后續的應用程序執行過程中間每個組件讀取
4、ConfigureServices, ConfigureLogging, Startup, Startup.ConfigureServices
用於往容器里注入應用的組件
5、Startup.Configure
用於注入中間件,處理 HttpContext 整個請求過程
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
Console.WriteLine("Startup.Configure");
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseFileServer();
app.UseWebSockets();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
在整個啟動的過程中,Startup 這個類不是必要的,只是讓代碼結構更加合理
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
Console.WriteLine("ConfigureWebHostDefaults");
//webBuilder.UseStartup<Startup>();
webBuilder.ConfigureServices(services =>
{
Console.WriteLine("webBuilder.ConfigureServices");
services.AddControllers();
});
webBuilder.Configure(app =>
{
Console.WriteLine("webBuilder.Configure");
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseFileServer();
app.UseWebSockets();
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
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddAuthentication();
services.AddAuthorization();
Console.WriteLine("Startup.ConfigureServices");
services.AddControllers();
}
中間件的注冊一般放在 Startup 的 Configure
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
Console.WriteLine("Startup.Configure");
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseFileServer();
app.UseWebSockets();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
GitHub源碼鏈接:
本作品采用知識共享署名-非商業性使用-相同方式共享 4.0 國際許可協議進行許可。
歡迎轉載、使用、重新發布,但務必保留文章署名 鄭子銘 (包含鏈接: http://www.cnblogs.com/MingsonZheng/ ),不得用於商業目的,基於本文修改后的作品務必以相同的許可發布。
如有任何疑問,請與我聯系 (MingsonZheng@outlook.com) 。