自從.NET 6 開始,微軟對應用的入口檔案進行了調整,移除了 Main 方法和 Startup 檔案,使用頂級語句的寫法,將應用初始化的相關設定和操作全部集中在 Program.cs 檔案中,如下:
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseAuthorization();
app.MapControllers();
app.Run();
關於頂級語句語法的規範,大家可以通過官方檔案瞭解一下:頂級語句。這種改變怎麼說呢,我自己是挺不習慣的,雖然這種方式更加簡潔,但是過於簡潔也容易讓人一臉懵,還是覺得之前的Startup檔案的方式根據邏輯清晰一點,也更能做到關注點分離。
.NET 6 下應用的構建有了一些區別,不再直接使用原來的 Host 進行設定構建,而是通過 WebApplication 的靜態方法構建 WebApplicationBuilder 來對主機進行設定,其實內部是 BootstrapHostBuilder 來進行的,呼叫 BootstrapHostBuilder 的相關設定方法時,只是將委託儲存起來,之後還是通過 HostingBuilder 來進行設定。
呼叫 Builder 生成 WebApplication 物件時,還是以前設定主機的那些操作,傳遞給 WebApplication 的也是 IHost 物件。
而最終呼叫 WebApplication 物件的 Run 方法啟動應用時,也是呼叫了主機的 StartAsync 方法,只是進行了一層包裝,微軟團隊這樣處理的好處暫時還不能很好得體會到。但總的來說改變也不大,雖然沒了Startup類,但整體框架的基本模型並沒有改變,之前能夠在 Startup 中拿到的東西,在現在的入口檔案中依舊可以拿到,我們依舊可以自由地控制整個請求管道,把握整體應用生命週期行為。
以下是 WebApplicationBuilder 物件 builder 張包含的幾個關鍵範例
// builder 中可以獲取到的幾個關鍵範例
// 依賴注入容器
IServiceCollection service = builder.Services;
// 設定
IConfiguration configuration = builder.Configuration;
// 紀錄檔
ILoggingBuilder loggingBuilder = builder.Logging;
// 主機
IHostBuilder host = builder.Host;
IWebHostBuilder webHost = builder.WebHost;
// 環境
IWebHostEnvironment env = builder.Environment;
現在的依賴注入設定,直接通過 builder.services進行設定即可
// 依賴注入,相當於 Startup 中的ConfigureService方法
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
紀錄檔驅動設定:
// 紀錄檔提供程式設定,相當於之前主機中的 hostBuilder.ConfigureLogging
builder.Logging.AddConsole().AddDebug();
以下是 WebApplication 物件 app 中包含的幾個關鍵範例
// app 中包含的幾個關鍵範例
// 環境
IWebHostEnvironment enviroment = app.Environment;
// 設定
IConfiguration config = app.Configuration;
// 應用生命週期
IHostApplicationLifetime lifetime = app.Lifetime;
// 紀錄檔記錄器
ILogger logger = app.Logger;
// 容器解析器
IServiceProvider serviceProvider = app.Services;
在執行完成 builder.Build(); 之後,應用已經初始化了依賴注入容器,所以我們可以通過 app.services獲取我們需要的範例。
// 通過容器獲取範例
var conf = app.Services.GetRequiredService<IConfiguration>();
當然,在 builder.Build(); 再通過builder.services 往容器中設定依賴注入關係是沒有用的了,會丟擲無效操作異常,因為容器已經建立,無法再修改。
根據頂級語句語法,頂級語句檔案中存在隱式 using 指令, 但如果我們需要在 Program.cs 檔案中額外引入一些名稱空間也是可以的,using語句需要在檔案的最前面,也可以定義方法或者類,只不過需要在頂級語句的後面,也可以使用非同步方法。
參考文章:
ASP.NET Core 系列:
目錄:ASP.NET Core 系列總結
上一篇:ASP.NET Core - IStartupFilter 與 IHostingStartup