ASP.NET Core 基礎知識(十二)【Host之通用主機】
.NET Core
應用配置和啟動“主機”。 主機負責應用程式啟動和生存期管理。 本主題介紹 ASP.NET Core
通用主機 (HostBuilder
),該主機對於託管不處理 HTTP 請求的應用非常有用。 有關 Web 主機 (WebHostBuilder
) 的介紹,請參閱 ASP.NET Core Web 主機
。
通用主機的目標是將 HTTP 管道從 Web 主機 API 中分離出來,從而啟用更多的主機方案。 基於通用主機的訊息、後臺任務和其他非 HTTP 工作負載可從橫切功能(如配置、依賴關係注入 [DI] 和日誌記錄)中受益。
通用主機是 ASP.NET Core 2.1
中的新增功能,不適用於 Web 承載方案。 對於 Web 承載方案,請使用 Web 主機
。 通用主機正處於開發階段,用於在未來版本中替換 Web 主機,並在 HTTP 和非 HTTP 方案中充當主要的主機 API。
在 Visual Studio Code 中執行示例應用時,請使用外部或整合終端。 請勿在 internalConsole
中執行示例。
在 Visual Studio Code 中設定控制檯:
- 開啟
.vscode/launch.json
檔案。 - 在 .NET Core 啟動(控制檯)配置中,找到控制檯條目。 將值設定為
externalTerminal
或integratedTerminal
。
介紹
通用主機庫位於 Microsoft.Extensions.Hosting
名稱空間中,由 Microsoft.Extensions.Hosting 包提供。Microsoft.AspNetCore.App 元包
(ASP.NET Core 2.1 或更高版本)中包括 Microsoft.Extensions.Hosting
包。
IHostedService
是執行程式碼的入口點。 每個 IHostedService
實現都按照 ConfigureServices 中服務註冊
的順序執行。 主機啟動時,每個 IHostedService
上都會呼叫 StartAsync
,主機正常關閉時,以反向註冊順序呼叫 StopAsync
。
設定主機
IHostBuilder
是供庫和應用初始化、生成和執行主機的主要元件:
public static async Task Main(string[] args)
{
var host = new HostBuilder()
.Build();
await host.RunAsync();
}
選項
HostOptions
配置 IHost
的選項。
關閉超時值
ShutdownTimeout
設定 StopAsync
的超時值。 預設值為 5 秒。
Program.Main
中的以下選項配置將預設值為 5 秒的關閉超時值增加至 20 秒:
var host = new HostBuilder()
.ConfigureServices((hostContext, services) =>
{
services.Configure<HostOptions>(option =>
{
option.ShutdownTimeout = System.TimeSpan.FromSeconds(20);
});
})
.Build();
預設服務
在主機初始化期間註冊以下服務:
環境 (IHostingEnvironment)
HostBuilderContext
- 配置 (
IConfiguration
) IApplicationLifetime(ApplicationLifetime)
IHostLifetime (ConsoleLifetime)
IHost
- 選項 (
AddOptions
) - 日誌記錄 (
AddLogging
)
主機配置
主機配置的建立方式如下:
- 呼叫
IHostBuilder
上的擴充套件方法以設定“內容根
”和“環境
”。 - 從
ConfigureHostConfiguration
中的配置提供程式讀取配置。
擴充套件方法
應用程式鍵(名稱)
IHostingEnvironment.ApplicationName
屬性是在主機構造期間通過主機配置設定的。 要顯式設定值,請使用 HostDefaults.ApplicationKey
:
金鑰:applicationName
型別:string
預設:包含應用入口點的程式集的名稱。
設定使用:HostBuilderContext.HostingEnvironment.ApplicationName
環境變數:<PREFIX_>APPLICATIONNAME
(<PREFIX_>
是使用者定義的可選字首)
內容根
此設定確定主機從哪裡開始搜尋內容檔案。
鍵:contentRoot
型別:string
預設值:預設為應用程式集所在的資料夾。
設定使用:UseContentRoot
環境變數:<PREFIX_>CONTENTROOT
(<PREFIX_>
是使用者定義的可選字首)
如果路徑不存在,主機將無法啟動。
var host = new HostBuilder()
.UseContentRoot("c:\\<content-root>")
環境
設定應用的環境
。
鍵:環境
型別:string
預設值:生產
設定使用:UseEnvironment
環境變數:<PREFIX_>ENVIRONMENT
(<PREFIX_>
是使用者定義的可選字首
)
環境可以設定為任何值。 框架定義的值包括 Development``Staging
和 Production
。 值不區分大小寫。
var host = new HostBuilder()
.UseEnvironment(EnvironmentName.Development)
ConfigureHostConfiguration
ConfigureHostConfiguration
使用 IConfigurationBuilder
來為主機建立 IConfiguration
。 主機配置用於初始化 IHostingEnvironment
,以供在應用的構建過程中使用。
可多次呼叫 ConfigureHostConfiguration
,並得到累計結果。 主機使用上一次在一個給定鍵上設定值的選項。
主機配置自動流向應用配置(ConfigureAppConfiguration
和應用的其餘部分)。
預設情況下不包括提供程式。 必須在 ConfigureHostConfiguration
中顯式指定應用所需的任何配置提供程式,包括:
- 檔案配置(例如,來自
hostsettings.json
檔案)。 - 環境變數配置。
- 命令列引數配置。
- 任何其他所需的配置提供程式。
通過使用 SetBasePath
指定應用的基本路徑,然後呼叫其中一個檔案配置提供程式
,可以啟用主機的檔案配置。 示例應用使用 JSON 檔案 hostsettings.json,並呼叫 AddJsonFile
來使用檔案的主機配置設定。
要新增主機的環境變數配置
,請在主機生成器上呼叫 AddEnvironmentVariables
。 AddEnvironmentVariables
接受使用者定義的字首(可選)。 示例應用使用字首 PREFIX_
。 當系統讀取環境變數時,便會刪除字首。 配置示例應用的主機後,PREFIX_ENVIRONMENT
的環境變數值就變成 environment
金鑰的主機配置值。
在開發過程中,如果使用 Visual Studio 或通過 dotnet run
執行應用,可能會在 Properties/launchSettings.json 檔案中設定環境變數。 若在開發過程中使用 Visual Studio Code,可能會在 .vscode/launch.json 檔案中設定環境變數。 有關更多資訊,請參見在 ASP.NET Core 中使用多個環境
。
通過呼叫 AddCommandLine
可新增命令列配置
。 最後新增命令列配置以允許命令列引數替代之前配置提供程式提供的配置。
hostsettings.json:
{
"environment": "Development"
}
可以通過applicationName
和 contentRoot
鍵提供其他配置。
示例 HostBuilder
配置使用 ConfigureHostConfiguration
:
var host = new HostBuilder()
.ConfigureHostConfiguration(configHost =>
{
configHost.SetBasePath(Directory.GetCurrentDirectory());
configHost.AddJsonFile("hostsettings.json", optional: true);
configHost.AddEnvironmentVariables(prefix: "PREFIX_");
configHost.AddCommandLine(args);
})
ConfigureAppConfiguration
通過在 IHostBuilder
實現上呼叫 ConfigureAppConfiguration
建立應用配置。 ConfigureAppConfiguration
使用 IConfigurationBuilder
來為應用建立 IConfiguration
。 可多次呼叫 ConfigureAppConfiguration
,並得到累計結果。 應用使用上一次在一個給定鍵上設定值的選項。 HostBuilderContext.Configuration
中提供 ConfigureAppConfiguration
建立的配置,以供進行後續操作和在 Services
中使用。
應用配置會自動接收 ConfigureHostConfiguration
提供的主機配置。
示例應用配置使用 ConfigureAppConfiguration
:
var host = new HostBuilder()
.ConfigureAppConfiguration((hostContext, configApp) =>
{
configApp.SetBasePath(Directory.GetCurrentDirectory());
configApp.AddJsonFile("appsettings.json", optional: true);
configApp.AddJsonFile(
$"appsettings.{hostContext.HostingEnvironment.EnvironmentName}.json",
optional: true);
configApp.AddEnvironmentVariables(prefix: "PREFIX_");
configApp.AddCommandLine(args);
})
appsettings.json:
{
"Logging": {
"LogLevel": {
"Default": "Warning"
}
},
"AllowedHosts": "*"
}
appsettings.Development.json:
{
"Logging": {
"LogLevel": {
"Default": "Debug",
"System": "Information",
"Microsoft": "Information"
}
}
}
appsettings.Production.json:
{
"Logging": {
"LogLevel": {
"Default": "Error",
"System": "Information",
"Microsoft": "Information"
}
}
}
要將設定檔案移動到輸出目錄,請在專案檔案中將設定檔案指定為MSBuild 專案項
。 示例應用移動具有以下 <Content>
項的 JSON 應用設定檔案和 hostsettings.json:
<ItemGroup>
<Content Include="**\*.json" Exclude="bin\**\*;obj\**\*" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>
ConfigureServices
ConfigureServices
將服務新增到應用的依賴關係
注入容器。 可多次呼叫 ConfigureServices
,並得到累計結果。
託管服務是一個類,具有實現 IHostedService
介面的後臺任務邏輯。 有關更多資訊,請參見在 ASP.NET Core 中使用託管服務實現後臺任務
。
示例應用使用 AddHostedService
擴充套件方法嚮應用新增生存期事件 LifetimeEventsHostedService
和定時後臺任務 TimedHostedService
服務:
var host = new HostBuilder()
.ConfigureServices((hostContext, services) =>
{
if (hostContext.HostingEnvironment.IsDevelopment())
{
// Development service configuration
}
else
{
// Non-development service configuration
}
services.AddHostedService<LifetimeEventsHostedService>();
services.AddHostedService<TimedHostedService>();
})
ConfigureLogging
ConfigureLogging
新增了一個委託來配置提供的ILoggingBuilder
。 可以利用相加結果多次呼叫 ConfigureLogging
。
var host = new HostBuilder()
.ConfigureLogging((hostContext, configLogging) =>
{
configLogging.AddConsole();
configLogging.AddDebug();
})
UseConsoleLifetime
UseConsoleLifetime
偵聽 Ctrl+C
/SIGINT 或 SIGTERM 並呼叫 StopApplication
來啟動關閉程式。 UseConsoleLifetime
解除阻止 RunAsync
和 WaitForShutdownAsync
等擴充套件。ConsoleLifetime
預註冊為預設生存期實現。 使用註冊的最後一個生存期。
var host = new HostBuilder()
.UseConsoleLifetime()
容器配置
為支援插入其他容器中,主機可以接受 IServiceProviderFactory<TContainerBuilder>
。 提供工廠不屬於 DI 容器註冊,而是用於建立具體 DI 容器的主機內部函式。 UseServiceProviderFactory(IServiceProviderFactory<TContainerBuilder>)
重寫用於建立應用的服務提供程式的預設工廠。
ConfigureContainer
方法託管自定義容器配置。 ConfigureContainer
提供在基礎主機 API 的基礎之上配置容器的強型別體驗。 可以利用相加結果多次呼叫 ConfigureContainer
。
為應用建立服務容器:
namespace GenericHostSample
{
internal class ServiceContainer
{
}
}
提供服務容器工廠:
using System;
using Microsoft.Extensions.DependencyInjection;
namespace GenericHostSample
{
internal class ServiceContainerFactory : IServiceProviderFactory<ServiceContainer>
{
public ServiceContainer CreateBuilder(IServiceCollection services)
{
return new ServiceContainer();
}
public IServiceProvider CreateServiceProvider(ServiceContainer containerBuilder)
{
throw new NotImplementedException();
}
}
}
使用該工廠併為應用配置自定義服務容器:
var host = new HostBuilder()
.UseServiceProviderFactory<ServiceContainer>(new ServiceContainerFactory())
.ConfigureContainer<ServiceContainer>((hostContext, container) =>
{
})
擴充套件性
在 IHostBuilder
上使用擴充套件方法實現主機擴充套件性。 以下示例介紹擴充套件方法如何使用 在 ASP.NET Core 中使用託管服務實現後臺任務
中所示的 TimedHostedService
示例來擴充套件 IHostBuilder
實現。
var host = new HostBuilder()
.UseHostedService<TimedHostedService>()
.Build();
await host.StartAsync();
應用建立 UseHostedService
擴充套件方法,以註冊在 T
中傳遞的託管服務:
using System;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
public static class Extensions
{
public static IHostBuilder UseHostedService<T>(this IHostBuilder hostBuilder)
where T : class, IHostedService, IDisposable
{
return hostBuilder.ConfigureServices(services =>
services.AddHostedService<T>());
}
}
管理主機
IHost
實現負責啟動和停止服務容器中註冊的 IHostedService
實現。
執行
Run
執行應用並阻止呼叫執行緒,直到關閉主機:
public class Program
{
public void Main(string[] args)
{
var host = new HostBuilder()
.Build();
host.Run();
}
}
RunAsync
RunAsync
執行應用並返回在觸發取消令牌或關閉時完成的 Task
:
public class Program
{
public static async Task Main(string[] args)
{
var host = new HostBuilder()
.Build();
await host.RunAsync();
}
}
RunConsoleAsync
RunConsoleAsync
啟用控制檯支援、生成和啟動主機,以及等待 Ctrl+C
/SIGINT 或 SIGTERM 關閉。
public class Program
{
public static async Task Main(string[] args)
{
var hostBuilder = new HostBuilder();
await hostBuilder.RunConsoleAsync();
}
}
Start
和 StopAsync
Start
同步啟動主機。
StopAsync
嘗試在提供的超時時間內停止主機。
public class Program
{
public static async Task Main(string[] args)
{
var host = new HostBuilder()
.Build();
using (host)
{
host.Start();
await host.StopAsync(TimeSpan.FromSeconds(5));
}
}
}
StartAsync
和 StopAsync
StartAsync
啟動應用。
StopAsync
停止應用。
public class Program
{
public static async Task Main(string[] args)
{
var host = new HostBuilder()
.Build();
using (host)
{
await host.StartAsync();
await host.StopAsync();
}
}
}
WaitForShutdown
WaitForShutdown
通過 IHostLifetime
觸發,例如 ConsoleLifetime
(偵聽 Ctrl+C
/SIGINT 或 SIGTERM)。 WaitForShutdown
呼叫 StopAsync
。
public class Program
{
public void Main(string[] args)
{
var host = new HostBuilder()
.Build();
using (host)
{
host.Start();
host.WaitForShutdown();
}
}
}
WaitForShutdownAsync
WaitForShutdownAsync
返回在通過給定的令牌和呼叫 StopAsync
來觸發關閉時完成的 Task
。
public class Program
{
public static async Task Main(string[] args)
{
var host = new HostBuilder()
.Build();
using (host)
{
await host.StartAsync();
await host.WaitForShutdownAsync();
}
}
}
外部控制元件
使用可從外部呼叫的方法,能夠實現主機的外部控制元件:
public class Program
{
private IHost _host;
public Program()
{
_host = new HostBuilder()
.Build();
}
public async Task StartAsync()
{
_host.StartAsync();
}
public async Task StopAsync()
{
using (_host)
{
await _host.StopAsync(TimeSpan.FromSeconds(5));
}
}
}
在 StartAsync
開始時呼叫 WaitForStartAsync
,在繼續之前,會一直等待該操作完成。 它可用於延遲啟動,直到外部事件發出訊號。
IHostingEnvironment
介面
IHostingEnvironment
提供有關應用託管環境的資訊。 使用建構函式注入
獲取 IHostingEnvironment
以使用其屬性和擴充套件方法:
public class MyClass
{
private readonly IHostingEnvironment _env;
public MyClass(IHostingEnvironment env)
{
_env = env;
}
public void DoSomething()
{
var environmentName = _env.EnvironmentName;
}
}
有關更多資訊,請參見在 ASP.NET Core 中使用多個環境
。
IApplicationLifetime
介面
IApplicationLifetime
允許啟動後和關閉活動,包括正常關閉請求。 介面上的三個屬性是用於註冊 Action
方法(用於定義啟動和關閉事件)的取消標記。
取消標記 | 觸發條件 |
---|---|
ApplicationStarted |
主機已完全啟動。 |
ApplicationStopped |
主機正在完成正常關閉。 應處理所有請求。 關閉受到阻止,直到完成此事件。 |
ApplicationStopping |
主機正在執行正常關閉。 仍在處理請求。 關閉受到阻止,直到完成此事件。 |
建構函式將 IApplicationLifetime
服務注入到任何類中。 示例應用將建構函式注入到 LifetimeEventsHostedService
類(一個 IHostedService
實現)中,用於註冊事件。
LifetimeEventsHostedService.cs:
internal class LifetimeEventsHostedService : IHostedService
{
private readonly ILogger _logger;
private readonly IApplicationLifetime _appLifetime;
public LifetimeEventsHostedService(
ILogger<LifetimeEventsHostedService> logger, IApplicationLifetime appLifetime)
{
_logger = logger;
_appLifetime = appLifetime;
}
public Task StartAsync(CancellationToken cancellationToken)
{
_appLifetime.ApplicationStarted.Register(OnStarted);
_appLifetime.ApplicationStopping.Register(OnStopping);
_appLifetime.ApplicationStopped.Register(OnStopped);
return Task.CompletedTask;
}
public Task StopAsync(CancellationToken cancellationToken)
{
return Task.CompletedTask;
}
private void OnStarted()
{
_logger.LogInformation("OnStarted has been called.");
// Perform post-startup activities here
}
private void OnStopping()
{
_logger.LogInformation("OnStopping has been called.");
// Perform on-stopping activities here
}
private void OnStopped()
{
_logger.LogInformation("OnStopped has been called.");
// Perform post-stopped activities here
}
}
StopApplication
請求終止應用。 以下類在呼叫類的 Shutdown
方法時使用 StopApplication
正常關閉應用:
public class MyClass
{
private readonly IApplicationLifetime _appLifetime;
public MyClass(IApplicationLifetime appLifetime)
{
_appLifetime = appLifetime;
}
public void Shutdown()
{
_appLifetime.StopApplication();
}
}
相關文章
- ASP.NET Core基礎知識(十一)【Host之Web 主機】ASP.NETWeb
- 翻譯 - ASP.NET Core 基本知識 - 通用主機 (Generic Host)ASP.NET
- 翻譯 - ASP.NET Core 基本知識 - Web 主機 (Web Host)ASP.NETWeb
- ASP.NET Core基礎知識(四)【路由】ASP.NET路由
- ASP.NET Core基礎知識(一)【概述】ASP.NET
- ASP.NET Core 2.2 基礎知識(六)【Configuration】ASP.NET
- ASP.NET Core 2.2 基礎知識(七)【選項】ASP.NET
- 十二、pytorch的基礎知識PyTorch
- JavaSE基礎知識分享(十二)Java
- ASP.NET Core基礎知識(二)【應用啟動】ASP.NET
- ASP.NET Core 2.2 基礎知識(十)【中介軟體】ASP.NET
- ASP.NET Core 2.2 基礎知識(十三)【伺服器】ASP.NET伺服器
- ASP.NET Core 2.2 基礎知識(八)【日誌記錄】ASP.NET
- ASP.NET Core 2.2 基礎知識(九)【處理錯誤】ASP.NET
- ASP.NET Core基礎知識(十四)【發出 HTTP 請求】ASP.NETHTTP
- ASP.NET Core基礎知識(三)【依賴關係注入(服務)】ASP.NET
- ASP.NET Core知識之RabbitMQ元件使用(二)ASP.NETMQ元件
- 理解ASP.NET Core - [04] HostASP.NET
- ASP.NET Core基礎知識(五)【環境(開發、分階段、生產)】ASP.NET
- Avalonia如何與通用主機Host整合實現MsDI
- Python基礎知識之字典Python
- Python基礎知識之集合Python
- MySQL指南之基礎知識MySql
- 小范筆記:ASP.NET Core API 基礎知識與Axios前端提交資料筆記ASP.NETAPIiOS前端
- Java基礎知識整理之this用法Java
- 介面測試之基礎知識
- Java基礎知識之概述(一)Java
- SAP SD基礎知識之維護中央信貸主資料
- 【Web前端基礎知識】CSS的定位機制之定位Web前端CSS
- 常用基礎知識面試(C++為主)面試C++
- 基礎知識
- Java基礎知識整理之註解Java
- 前端基礎知識複習之CSS前端CSS
- 前端基礎知識複習之html前端HTML
- SAP SD基礎知識之稅(Taxes)
- Python入門之基礎知識(一)Python
- Golang 基礎之併發知識 (三)Golang
- JVM學習之JVM基礎知識JVM