asp.net core 系列 17 通用主機 IHostBuilder


一.概述

  ASP.NET Core 通用主機 (HostBuilder),該主機對於托管不處理 HTTP 請求的應用非常有用。通用主機的目標是將 HTTP 管道從 Web 主機 API 中分離出來,從而啟用更多的主機方案。 基於通用主機的消息、后台任務和其他非 HTTP 工作負載可從橫切功能(如配置、依賴關系注入 [DI] 和日志記錄)中受益。通用主機是 ASP.NET Core 2.1 中的新增功能,不適用於 Web 承載方案。通用主機正處於開發階段,用於在未來版本中替換 Web 主機,並在 HTTP 和非 HTTP 方案中充當主要的主機 API

  通用主機庫位於 Microsoft.Extensions.Hosting 命名空間中,而web主機庫位於Microsoft.AspNetCore.Hosting命令空間中。

  PM> Install-Package Microsoft.AspNetCore.Hosting.Abstractions -Version 2.2.0

 

  1.1 設置主機

    IHostBuilder 是供庫和應用初始化、生成和運行主機的主要組件。(官方文檔中main方法是使用的異步,但本人vs程序啟動時提示找不到mian方法,只好改成了同步) 。

        public static  void Main(string[] args)
        {
            var host = new HostBuilder()
                .Build();
             host.Run();
        }

    

  1.2 默認服務

    在主機初始化期間注冊以下服務:

                   環境 (IHostingEnvironment)

                   HostBuilderContext

                   配置 (IConfiguration)

                   IApplicationLifetime (ApplicationLifetime)

                   IHostLifetime (ConsoleLifetime)

                   IHost

                   選項 (AddOptions)

                   日志記錄 (AddLogging)

 

  1.3 主機配置 ConfigureHostConfiguration 

    主機配置的創建方式如下:

        調用 IHostBuilder 上的擴展方法以設置“內容根”和“環境”。

             從 ConfigureHostConfiguration 中的配置提供程序讀取配置。

    (1) ConfigureHostConfiguration 主機配置

      通用主機配置與web主機配置還是有些區別,在通用主機中有ConfigureHostConfiguration用來配置主機。主機配置用於初始化 IHostingEnvironment,以供在應用的構建過程中使用。可多次調用 ConfigureHostConfiguration,並得到累計結果。必須在 ConfigureHostConfiguration 中顯式指定應用所需的任何配置提供程序,包括:

           1)文件配置(例如,來自 hostsettings.json 文件)。

           2)環境變量配置。

           3)命令行參數配置。

           4)任何其他所需的配置提供程序。

      通過使用 SetBasePath 指定應用的基本路徑,然后調用其中一個文件配置提供程序,可以啟用主機的文件配置。

    (2) AddEnvironmentVariables 環境變量

      要添加主機的環境變量配置,請在主機生成器上調用 AddEnvironmentVariables。 示例應用使用前綴 PREFIX_。 當系統讀取環境變量時,便會刪除前綴。 配置示例應用的主機后,PREFIX_ENVIRONMENT 的環境變量值就變成 environment密鑰的主機配置值。

    (3) AddCommandLine 命令行參數

      通過 dotnet run 運行應用 指定參數時,通過調用 AddCommandLine 可添加命令行配置。

 

  1.4 應用配置 ConfigureAppConfiguration

     調用 ConfigureAppConfiguration 創建應用配置,在web主機中也有介紹。這里就不再說明。 主機配置和應用配置都可以做配置使用,主機配置重點在主機環境的配置(IHostingEnvironment)。

 

  1.5 ConfigureServices

    ConfigureServices 將服務添加到應用的依賴關系注入容器。 可多次調用 ConfigureServices,並得到累計結果。這個在web主機中常用。 值得注意的是:除了三種注入的實例生命周期(asp.net core 系列 4 注入服務的生存期)。還可以注入THostedService類型服務,專門用於做后台服務的。

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>();
    })

  

  1.6 IApplicationLifetime 接口

    IApplicationLifetime接口在上篇介紹web主機進有講過,這里不在具體介紹。下面會有代碼演示,實現一個IHostedService類型服務,在服務中用於注冊事件。

 

 二. 完整示例

  使用通用主機來演示一個后台服務。使用控制台做宿主,后台服務定時每隔5秒執行一次。該演示包括主機配置、應用配置、服務容器注入、日志配置。還包括注入二個IHostedService類型的服務。其中TimedHostedService類用於做后台定時服務,LifetimeEventsHostedService類注入服務IApplicationLifetime事件,監聽服務運行狀態。

  完整示例github地址:

    https://github.com/aspnet/Docs/tree/master/aspnetcore/fundamentals/host/generic-host/samples/2.x/GenericHostSample

public class Program
    {

        /// <summary>
        /// 使用控制台做承載的后台服務
        /// </summary>
        /// <param name="args"></param>
        public static void Main(string[] args)
        {
            var host = new HostBuilder()
                .ConfigureHostConfiguration(configHost =>
                {
                    configHost.SetBasePath(Directory.GetCurrentDirectory());
                    configHost.AddJsonFile("hostsettings.json", optional: true);
                    configHost.AddEnvironmentVariables(prefix: "PREFIX_");
                    configHost.AddCommandLine(args);
                })
                .ConfigureAppConfiguration((hostContext, configApp) =>
                {
                    configApp.AddJsonFile("appsettings.json", optional: true);
                    configApp.AddJsonFile(
                        $"appsettings.{hostContext.HostingEnvironment.EnvironmentName}.json",
                        optional: true);
                    configApp.AddEnvironmentVariables(prefix: "PREFIX_");
                    configApp.AddCommandLine(args);
                })
                .ConfigureServices((hostContext, services) =>
                {
                    //注冊后台普通服務
                    // services.AddSingleton<IJobTimeService, JobTimeService>();
                    //注冊后台THostedService類型服務
                    services.AddHostedService<LifetimeEventsHostedService>();
                    services.AddHostedService<TimedHostedService>();
                })
                .ConfigureLogging((hostContext, configLogging) =>
                {
                    configLogging.AddConsole();
                    configLogging.AddDebug();

                })
                .UseConsoleLifetime()
                .Build();

            //實例化注入的普通服務
           // IJobTimeService job = host.Services.GetRequiredService<IJobTimeService>();
           // job.Time();
            host.Run();
        }
}

   

    /// <summary>
    ///監聽服務運行狀態
    /// </summary>
    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
        }
    }

 

    /// <summary>
    /// 后台定時服務
    /// </summary>
    internal class TimedHostedService : IHostedService, IDisposable
    {
        private readonly ILogger _logger;
        private Timer _timer;

        public TimedHostedService(ILogger<TimedHostedService> logger)
        {
            _logger = logger;
        }

        public Task StartAsync(CancellationToken cancellationToken)
        {
            _logger.LogInformation("Timed Background Service is starting.");

            _timer = new Timer(DoWork, null, TimeSpan.Zero,
                TimeSpan.FromSeconds(5));

            return Task.CompletedTask;
        }

        /// <summary>
        /// 每隔5秒執行一次
        /// </summary>
        /// <param name="state"></param>
        private void DoWork(object state)
        {
            _logger.LogInformation("Timed Background Service is working.");
        }

        public Task StopAsync(CancellationToken cancellationToken)
        {
            _logger.LogInformation("Timed Background Service is stopping.");

            _timer?.Change(Timeout.Infinite, 0);

            return Task.CompletedTask;
        }

        public void Dispose()
        {
            _timer?.Dispose();
        }
    }
-- hostsettings.json文件
{
  "environment": "Development"
}

 

 參考文獻:

    官方文檔:ASP.NET Core 通用主機

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM