一.概述 在asp.net core中,Host主機負責應用程式啟動和生存期管理。host主機包括Web 主機(IWebHostBuilder)和通用主機(IHostBuilder)。Web 主機是適用於托管 Web 應用;通用主機(ASP.NET Core 2.1 或更高版本)是適用於托管非 We ...
一.概述
在asp.net core中,Host主機負責應用程式啟動和生存期管理。host主機包括Web 主機(IWebHostBuilder)和通用主機(IHostBuilder)。Web 主機是適用於托管 Web 應用;通用主機(ASP.NET Core 2.1 或更高版本)是適用於托管非 Web 應用;在未來的版本中,通用主機將適用於托管任何類型的應用,包括 Web 應用。 通用主機最終將取代 Web 主機。本篇先來瞭解ASP.NET Core Web主機。
1.1 設置Web主機以及執行的任務
創建使用 IWebHostBuilder 實例的主機。 通常在應用的入口點 Main 方法中執行。 在項目模板中,Main 位於 Program.cs。
public static IWebHostBuilder CreateWebHostBuilder(string[] args) => WebHost.CreateDefaultBuilder(args) .UseStartup<Startup>();
下麵詳細說下CreateDefaultBuilder 執行的下列任務:
(1) 將內置的 Kestrel 伺服器配置為 Web 伺服器。
(2) 設置content root 內容根路徑,並由 Directory.GetCurrentDirectory 返回的路徑。
(3) 通過以下載入主機配置:
首碼為 ASPNETCORE_ 的環境變數(例如,ASPNETCORE_ENVIRONMENT)。
命令行參數。
(4) 按以下順序載入應用配置
appsettings.json。
appsettings.{Environment}.json。
應用在使用入口程式集的 Development 環境中運行時的機密管理器。
環境變數。
命令行參數。
(5) 設置console and debug 輸出的日誌記錄。在 appsettings.json 或 appsettings.{Environment}.json 文件的日誌記錄配置部分(Logging)中指定的日誌篩選規則。
(6) ASP.NET Core 模塊使用IIS托管運行時,CreateDefaultBuilder 會啟用 IIS 集成,這會配置應用的基址和埠。 IIS 集成還配置應用以捕獲啟動錯誤。
(7) 如果應用環境為“開發”,請將 ServiceProviderOptions.ValidateScopes 設為 true。
1.2 Web主機的擴展配置
IWebHostBuilder下的ConfigureAppConfiguration、ConfigureLogging 以及其他方法可重寫(第三大點講)和增強 CreateDefaultBuilder 定義的配置。 下麵是一些示例:
(1) ConfigureAppConfiguration
ConfigureAppConfiguratio用於指定應用的 IConfiguration。下麵的 ConfigureAppConfiguration 調用添加委托,以在 appsettings.xml 文件中添加應用配置。 可多次調用 ConfigureAppConfiguration。具體參照 ”asp.net core 系列 10 配置configuration“ 。
WebHost.CreateDefaultBuilder(args) .ConfigureAppConfiguration((hostingContext, config) => { config.AddXmlFile("appsettings.xml", optional: true, reloadOnChange: true); })
(2) ConfigureLogging
ConfigureLogging調用添加委托,以將最小日誌記錄級別 (SetMinimumLevel) 配置為 LogLevel.Warning。 此設置重寫 CreateDefaultBuilder 在 appsettings.Development.json 和 appsettings.Production.json 中配置的設置,分別為 LogLevel.Debug 和 LogLevel.Error。 可多次調用 ConfigureLogging。具體參照 “asp.net core 系列 13 日誌”。
WebHost.CreateDefaultBuilder(args) .ConfigureLogging(logging => { logging.SetMinimumLevel(LogLevel.Warning); })
(3) ConfigureKestrel
下麵調用 ConfigureKestrel 來重寫 CreateDefaultBuilder 在配置 Kestrel 時預設的 30,000,000 位元組,大約為28.6MB。MaxRequestBodySize是獲取或設置任何請求主體的最大允許大小(以位元組為單位)。設置為null時,最大請求正文大小不受限制。
WebHost.CreateDefaultBuilder(args) .ConfigureKestrel((context, options) => { options.Limits.MaxRequestBodySize = 20000000; });
二.主機配置值
WebHostBuilder 依賴於以下的方法設置主機配置值:
(1)主機生成器配置,其中包括格式 ASPNETCORE_{configurationKey} 的環境變數。 例如 ASPNETCORE_ENVIRONMENT。
(2)UseContentRoot 和 UseConfiguration 等擴展。
(3)UseSetting 和關聯鍵。 使用 UseSetting 設置值時,該值設置為無論何種類型的字元串。
2.1 Application Key (Name)
在主機構造期間調用 UseStartup 或 Configure 時,會自動設置 IHostingEnvironment.ApplicationName 屬性。 該預設值設置為應用入口點的程式集的名稱。 要顯式設置值,請使用 WebHostDefaults.ApplicationKey。環境變數:ASPNETCORE_APPLICATIONNAME
public void Configure(IApplicationBuilder app, IHostingEnvironment env) { //應用程式預設名稱為:MyNetCoreStudy (也就是項目名稱) string s = env.ApplicationName; //..
//顯示設置
WebHost.CreateDefaultBuilder(args) .UseSetting(WebHostDefaults.ApplicationKey, "CustomApplicationName")
2.2捕獲啟動錯誤
啟動錯誤的捕獲。 預設為 false, 啟動期間出錯,主機退出。當 true 時,主機在啟動期間捕獲異常並嘗試啟動伺服器。當程式使用 Kestrel 在 IIS 後方運行,預設值是 true。環境變數:ASPNETCORE_CAPTURESTARTUPERRORS
WebHost.CreateDefaultBuilder(args) .CaptureStartupErrors(true)
2.3 內容根
設置確定web根目錄的基路徑。用於搜索的內容文件,比如mvc的視圖。預設為應用程式集所在的文件夾。環境變數:ASPNETCORE_CONTENTROOT。
WebHost.CreateDefaultBuilder(args) .UseContentRoot("c:\\<content-root>")
2.4 詳細錯誤
確定是否應捕獲詳細錯誤。預設值:false。啟用為true時,會捕獲詳細的異常。或當環境設置為 Development時也會捕獲詳細的異常。 環境變數 ASPNETCORE_DETAILEDERRORS
WebHost.CreateDefaultBuilder(args) .UseSetting(WebHostDefaults.DetailedErrorsKey, "true")
2.5 環境
設置應用的環境。預設值:Production。 使用 Visual Studio 時,可能會在 launchSettings.json 文件中設置環境變數。環境變數:ASPNETCORE_ENVIRONMENT
WebHost.CreateDefaultBuilder(args)
.UseEnvironment(EnvironmentName.Development)
2.6 HTTPS 埠
設置 HTTPS 重定向埠。 用於強制實施 HTTPS。 環境變數:ASPNETCORE_HTTPS_PORT。
WebHost.CreateDefaultBuilder(args) .UseSetting("https_port", "8080")
2.7 伺服器 (Kestrel) URL
指示 IP 地址或主機地址,host啟動時偵聽。預設: http://localhost:5000。設置為伺服器響應的以分號分隔 (;) 的 URL 首碼列表。環境變數:ASPNETCORE_URLS
WebHost.CreateDefaultBuilder(args) .UseUrls("http://*:5000;http://localhost:5001;https://hostname:5002")
三.重寫(覆蓋)配置
配置可用於配置 Web 主機。 在下麵的示例中,主機配置是根據需要在 hostsettings.json 文件中指定。 命令行參數可能會重寫從 hostsettings.json 文件載入的任何配置。 生成的配置(在 config 中)用於通過 UseConfiguration 配置主機。 IWebHostBuilder 配置會添加到應用配置中。
hostsettings.json { urls: "http://*:5005" }
public static IWebHostBuilder CreateWebHostBuilder(string[] args) { //IConfiguration的配置主機 var config = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) //主機配置在hostsettings.json 文件中指定 .AddJsonFile("hostsettings.json", optional: true) // 命令行參數可能會重寫從 hostsettings.json 文件載入的任何配置 .AddCommandLine(args) .Build(); return WebHost.CreateDefaultBuilder(args) .UseUrls("http://*:5000") //config重寫UseUrls .UseConfiguration(config) .Configure(Handle1); } private static void Handle1(IApplicationBuilder app) { app.Run(async context => { await context.Response.WriteAsync("Handle1 Test 1"); }); }
如果在執行 dotnet 運行時從命令提示符傳入。 命令行參數,將重寫 hostsettings.json 文件中的 urls 值,且伺服器偵聽埠 8080。
dotnet run --urls "http://*:8080"
啟動時,url參數重寫的的關係是:UseUrls被hostsettings.json重寫, hostsettings.json又被命令行參數重寫。
四 .管理主機
對於啟動主機有二種方式:run和start。使用Run
方法啟動 Web 應用是阻止調用線程,直到顯示關閉主機。使用start方法是非阻止方式運行主機。具體用法請查看官網。
// Runs a web application and block the calling thread until host shutdown. CreateWebHostBuilder(args).Build().Run();
CreateWebHostBuilder(args).Build().Start(); //非阻止方式,所有必須加上ReadLine, Console.ReadLine();
五. IHostingEnvironment 介面
IHostingEnvironment 介面提供有關應用的 Web 承載環境的信息,預設是將 IHostingEnvironment
註入到 Startup
構造函數,在Configure方法中引用。下麵使用構造函數註入獲取 IHostingEnvironment 以使用其屬性和擴展方法:
public class CustomFileReader { private readonly IHostingEnvironment _env; public CustomFileReader(IHostingEnvironment env) { _env = env; } public string ReadFile(string filePath) { //返回IFileProvider,指向 WebRootPath var fileProvider = _env.WebRootFileProvider; // Process the file here } }
創建自定義中間件時可以將 IHostingEnvironment 註入 Invoke 方法(參考asp.net core 系列 15 中間件):
public async Task Invoke(HttpContext context, IHostingEnvironment env) { if (env.IsDevelopment()) { // Configure middleware for Development } else { // Configure middleware for Staging/Production } var contentRootPath = env.ContentRootPath; }
六.IApplicationLifetime 介面
IApplicationLifetime 用於應用程式在啟動和關閉時的活動。 介面上的三個屬性是用於註冊 Action
方法。用於定義啟動和關閉事件標記。
public class Startup { public void Configure(IApplicationBuilder app, IApplicationLifetime appLifetime) { appLifetime.ApplicationStarted.Register(OnStarted); appLifetime.ApplicationStopping.Register(OnStopping); appLifetime.ApplicationStopped.Register(OnStopped); Console.CancelKeyPress += (sender, eventArgs) => { appLifetime.StopApplication(); // Don't terminate the process immediately, wait for the Main thread to exit gracefully. eventArgs.Cancel = true; }; } private void OnStarted() { // Perform post-startup activities here } private void OnStopping() { // Perform on-stopping activities here } private void OnStopped() { // Perform post-stopped activities here } }
七. 作用域驗證
如果應用環境為“開發”,則 CreateDefaultBuilder 將 ServiceProviderOptions.ValidateScopes 設為 true。若將 ValidateScopes 設為 true,預設服務提供程式會執行檢查來驗證以下內容:
作用域服務不能直接或間接地從根服務提供者解析。
作用域服務不會直接或間接地註入到單例中(服務的生存期)。
WebHost.CreateDefaultBuilder(args) .UseDefaultServiceProvider((context, options) => { options.ValidateScopes = true; })
當true將執行檢查,驗證作用域服務,永遠不會從根提供程式解析(不從頂級容器中獲取scoped生命周期服務,所有服務都是註入到容器中IServiceCollection)。 mark:沒有完全理解,以後再說。
參考文獻:
官方文檔:ASP.NET Core Web主機