一、介紹
官方文檔中說,Microsoft.AspNetCore.App 元包(ASP.NET Core 2.1 或更高版本)包含通用主機的Microsoft.Extensions.Hosting包,當創建控制台項目以后並沒有相應的包。
在官方案例中所用的Nuget包有:
1. Microsoft.Extensions.Hosting
2. Microsoft.Extensions.Configuration.Json
3. Microsoft.Extensions.Configuration.EnvironmentVariables
4. Microsoft.Extensions.Configuration.CommandLine
5. Microsoft.Extensions.DependencyInjection
6. Microsoft.Extensions.Logging.Console
7. Microsoft.Extensions.Logging.Debug
托管服務實現 IHostedService 接口並且是執行代碼的入口點。 每個 IHostedService 實現都按照 ConfigureServices 中服務注冊的順序執行。 主機啟動時,每個 IHostedService 上都會調用 StartAsync。主機正常關閉時,以反向注冊順序調用 StopAsync。
托管服務還有,BackgroundService:排隊的后台任務,IScopedProcessingService:有作用域的服務
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using System; using System.IO; namespace Haos.Develop.HostBuilders.Samples { class Program { static void Main(string[] args) { //Microsoft.Extensions.Hosting var host = new HostBuilder() .ConfigureHostConfiguration(builder => { //Microsoft.Extensions.Configuration.Json builder.AddJsonFile("hostsettings.json", true); builder.AddJsonFile("appsettings.json", true); }) .ConfigureAppConfiguration((context, builder) => { var temp = context.Configuration["AllowedHosts"]; context.HostingEnvironment.ApplicationName = "this_is_text_host"; builder.SetBasePath(Directory.GetCurrentDirectory()); //Microsoft.Extensions.Configuration.EnvironmentVariables builder.AddEnvironmentVariables("PREFIX_HAOS_"); //Microsoft.Extensions.Configuration.CommandLine builder.AddCommandLine(args); }) .ConfigureServices((context, services) => { services.AddHostedService<MyHostedService>(); }) .ConfigureLogging((logging) => { //Microsoft.Extensions.Logging.Console logging.AddConsole(); //Microsoft.Extensions.Logging.Debug logging.AddDebug(); }) .UseConsoleLifetime() .Build(); host.Run(); } } }
二、主機配置
默認的情況下,是不配置主機環境變量。需要配置可以調用ConfigureHostConfiguration和ConfigureAppConfiguration方法進行配置,並且他們可以同時調用多次得到累計結果
var host = new HostBuilder() .ConfigureHostConfiguration(builder => { builder.AddJsonFile("hostsettings.json", true); }) .ConfigureHostConfiguration(builder => { builder.AddJsonFile("appsettings.json", true); }) .ConfigureAppConfiguration((context, builder) => {//應用入口點的程序集的名稱 context.HostingEnvironment.ApplicationName = "this_is_text_host"; //確定主機從哪里開始搜索內容文件 builder.SetBasePath(Directory.GetCurrentDirectory()); //設置應用的環境 builder.AddEnvironmentVariables("PREFIX_HAOS_"); })
代碼中調用兩次ConfigureHostConfiguration方法都是加載配置文件。加載的文件在當前方法無法獲取到文件的類容。例如第一次調用加載hostsettings.json文件無法立刻獲取改文件內容。在加載appsettings.json這個方法里就能拿到hostsettings.json的內容
三、依賴關系注入,配置日志
ConfigureServices:將服務添加到應用的依賴關系注入容器。 可多次調用 ConfigureServices,並得到累計結果。
ConfigureLogging:添加一個委托,用於配置提供的 ILoggingBuilder。 可以利用相加結果多次調用 ConfigureLogging
var host = new HostBuilder() .ConfigureServices((context, services) => { //Microsoft.Extensions.DependencyInjection services.AddHostedService<MyHostedService>(); }) .ConfigureLogging((logging) => { //Microsoft.Extensions.Logging.Console logging.AddConsole(); //Microsoft.Extensions.Logging.Debug logging.AddDebug(); })
四、IApplicationLifetime接口和IHostedService接口的實現類
IApplicationLifetime 允許啟動后和關閉活動,包括正常關閉請求。通過構造函數將 IApplicationLifetime 服務注入到任何類中,用於注冊事件
ApplicationStarted:完全啟動觸發,ApplicationStopped:正在完成關閉觸發,ApplicationStopping:正在執行關閉觸發
StopApplication() 方法用於關閉整個主機
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; using System.Text; using System.Threading; using System.Threading.Tasks; namespace Haos.Develop.HostBuilders.Samples { public class MyHostedService : IHostedService { /// <summary> /// 日志 /// </summary> private readonly ILogger _looger; /// <summary> /// 配置 /// </summary> private readonly IConfiguration _configuration; private readonly IApplicationLifetime _applicationLifetime; public MyHostedService(ILogger<MyHostedService> logger,IConfiguration configuration,IApplicationLifetime applicationLifetime) { _looger = logger; _configuration = configuration; _applicationLifetime = applicationLifetime; } public Task StartAsync(CancellationToken cancellationToken) { return Task.Run(() => { var stringStr = _configuration["Test_Code"]; //主機已完全啟動 _applicationLifetime.ApplicationStarted.Register(() => _looger.LogInformation("status is started")); //主機正在完成正常關閉,應處理所有請求 _applicationLifetime.ApplicationStopped.Register(()=> _looger.LogInformation(stringStr)); //主機正在執行正常關閉,仍在處理請求 _applicationLifetime.ApplicationStopping.Register(() => _looger.LogInformation("status is Stopping")); int i = 1; Timer timer = new Timer(a => { if (i == 2) Close(); i++; _looger.LogWarning("測試輸出!"); }, null, 3000, 5000); }); } public Task StopAsync(CancellationToken cancellationToken) { return Task.Run(() => { _looger.LogInformation("Application Shutdown"); Console.Read(); }); } /// <summary> /// 請求應用終止.(整個應用) /// </summary> public void Close() { _applicationLifetime.StopApplication(); } } }