泛型主机

.NET 通用主机

本文介绍了 .NET Core 泛型主机 (HostBuilder) 并提供有关使用方法的指南。

什么是主机?

主机是封装应用资源的对象,例如 :

  • 依赖关系注入 (DI)
  • Logging
  • 配置
  • IHostedService 实现

启动主机时,它对它在 DI 容器中找到的 IHostedService 的每个实现调用 IHostedService.StartAsync 在 web 应用中,其中一个 IHostedService 实现是启动 HTTP 服务器实现的 web 服务。

一个对象中包含所有应用的相互依赖资源的主要原因是生存期管理:控制应用启动和正常关闭。

在低于 3.0 的 ASP.NET Core 版本中,Web 主机用于 HTTP 工作负载。 不再建议将 Web 主机用于 Web 应用,但该主机仍可仅用于后向兼容性。

设置主机

主机通常由 Program 类中的代码配置、生成和运行。 Main 方法:

  • 调用 CreateHostBuilder 方法以创建和配置生成器对象。
  • 对生成器对象调用 BuildRun 方法。

以下是用于非 HTTP 工作负载的 Program.cs 代码,其中单个 IHostedService 实现添加到 DI 容器。

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureServices((hostContext, services) =>
            {
               services.AddHostedService<Worker>();
            });
}

对于 HTTP 工作负荷,Main 方法相同,但 CreateHostBuilder 调用 ConfigureWebHostDefaults

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
        });

如果应用使用 Entity Framework Core,不要更改 CreateHostBuilder 方法的名称或签名。 Entity Framework Core 工具应查找一个无需运行应用即可配置主机的 CreateHostBuilder 方法。 有关详细信息,请参阅设计时 DbContext 创建

默认生成器设置

CreateDefaultBuilder 方法:

  • 内容根目录设置为由 GetCurrentDirectory 返回的路径。
  • 通过以下项加载主机配置:
    • 前缀为“DOTNET_”的环境变量。
    • 命令行参数。
  • 通过以下对象加载应用配置:
    • appsettings.json 。
    • appsettings.{Environment}.json 。
    • 密钥管理器 当应用在 Development 环境中运行时。
    • 环境变量。
    • 命令行参数。
  • 添加以下日志记录提供程序:
    • 控制台
    • 调试
    • EventSource
    • EventLog(仅当在 Windows 上运行时)
  • 当环境为“开发”时,启用范围验证依赖关系验证

ConfigureWebHostDefaults 方法:

本文中后面的所有应用类型的设置 web 应用的设置部分介绍如何替代默认生成器设置。

框架提供的服务

自动注册的服务包括:

有关框架提供的服务的详细信息,请参阅 在 ASP.NET Core 依赖注入

IHostApplicationLifetime

IHostApplicationLifetime(以前称为 IApplicationLifetime)服务注入任何类以处理启动后和正常关闭任务。 接口上的三个属性是用于注册应用启动和应用停止事件处理程序方法的取消令牌。 该接口还包括 StopApplication 方法。

以下示例是注册 IHostApplicationLifetime 事件的 IHostedService 实现:

internal class LifetimeEventsHostedService : IHostedService
{
    private readonly ILogger _logger;
    private readonly IHostApplicationLifetime _appLifetime;

    public LifetimeEventsHostedService(
        ILogger<LifetimeEventsHostedService> logger, 
        IHostApplicationLifetime 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
    }
}

IHostLifetime

IHostLifetime 实现控制主机何时启动和何时停止。 使用了已注册的最后一个实现。

Microsoft.Extensions.Hosting.Internal.ConsoleLifetime 是默认的 IHostLifetime 实现。 ConsoleLifetime

IHostEnvironment

IHostEnvironment 服务注册到一个类,获取关于以下项的信息:

Web 应用实现 IWebHostEnvironment 接口,该接口继承 IHostEnvironment 并添加 WebRootPath

主机配置

主机配置用于 IHostEnvironment 实现的属性。

主机配置可以从 ConfigureAppConfiguration 内的 HostBuilderContext.Configuration 获取。 ConfigureAppConfiguration 后,HostBuilderContext.Configuration 被替换为应用配置。

若要添加主机配置,请对 IHostBuilder 调用 ConfigureHostConfiguration 可多次调用 ConfigureHostConfiguration,并得到累计结果。 主机使用上一次在一个给定键上设置值的选项。

CreateDefaultBuilder 包含前缀为 DOTNET_ 的环境变量提供程序和命令行参数。 对于 web 应用程序,添加前缀为 ASPNETCORE_ 的环境变量提供程序。 当系统读取环境变量时,便会删除前缀。 例如,ASPNETCORE_ENVIRONMENT 的环境变量值就变成 environment 密钥的主机配置值。

以下示例创建主机配置:

// using Microsoft.Extensions.Configuration;

Host.CreateDefaultBuilder(args)
    .ConfigureHostConfiguration(configHost =>
    {
        configHost.SetBasePath(Directory.GetCurrentDirectory());
        configHost.AddJsonFile("hostsettings.json", optional: true);
        configHost.AddEnvironmentVariables(prefix: "PREFIX_");
        configHost.AddCommandLine(args);
    });

应用配置

通过对 IHostBuilder 调用 ConfigureAppConfiguration 创建应用配置。 可多次调用 ConfigureAppConfiguration,并得到累计结果。 应用使用上一次在一个给定键上设置值的选项。

ConfigureAppConfiguration 创建的配置可以通过 HostBuilderContext.Configuration 获取以用于后续操作,也可以通过 DI 作为服务获取。 主机配置也会添加到应用配置。

有关详细信息,请参阅 ASP.NET Core 中的配置

适用于所有应用类型的设置

本部分列出了适用于 HTTP 和非 HTTP 工作负荷的主机设置。 默认情况下,用来配置这些设置的环境变量可以具有 DOTNET_ASPNETCORE_ 前缀。

ApplicationName

IHostEnvironment.ApplicationName 属性是在主机构造期间通过主机配置设定的。

密钥:applicationName
类型:string
默认:包含应用入口点的程序集的名称。 环境变量<PREFIX_>APPLICATIONNAME

要设置此值,请使用环境变量。

ContentRootPath

IHostEnvironment.ContentRootPath 属性决定主机从什么位置开始搜索内容文件。 如果路径不存在,主机将无法启动。

:contentRoot
类型:string
默认:应用程序集所在的文件夹。
环境变量<PREFIX_>CONTENTROOT

若要设置此值,请使用环境变量或对 IHostBuilder 调用 UseContentRoot

Host.CreateDefaultBuilder(args)
    .UseContentRoot("c:\\content-root")
    //...

有关详细信息,请参见:

EnvironmentName

IHostEnvironment.EnvironmentName 属性可以设置为任何值。 框架定义的值包括 Development``StagingProduction 值不区分大小写。

:环境
类型:string
默认值:生产
环境变量<PREFIX_>ENVIRONMENT

若要设置此值,请使用环境变量或对 IHostBuilder 调用 UseEnvironment

Host.CreateDefaultBuilder(args)
    .UseEnvironment("Development")
    //...

ShutdownTimeout

HostOptions.ShutdownTimeout 设置 StopAsync 的超时。 默认值为 5 秒。 在超时时间段中,主机:

如果在所有托管服务停止之前就达到了超时时间,则会在应用关闭时会终止剩余的所有活动的服务。 即使没有完成处理工作,服务也会停止。 如果停止服务需要额外的时间,请增加超时时间。

:shutdownTimeoutSeconds
类型:int
默认:5 秒 环境变量<PREFIX_>SHUTDOWNTIMEOUTSECONDS

若要设置此值,请使用环境变量或配置 HostOptions 以下示例将超时设置为 20 秒:

Host.CreateDefaultBuilder(args)
    .ConfigureServices((hostContext, services) =>
    {
        services.Configure<HostOptions>(option =>
        {
            option.ShutdownTimeout = System.TimeSpan.FromSeconds(20);
        });
    });

适用于 Web 应用的设置

一些主机设置仅适用于 HTTP 工作负荷。 默认情况下,用来配置这些设置的环境变量可以具有 DOTNET_ASPNETCORE_ 前缀。

IWebHostBuilder 上的扩展方法适用于这些设置。 显示如何调用扩展方法的示例代码假定 webBuilderIWebHostBuilder 的实例,如以下示例所示:

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.CaptureStartupErrors(true);
            webBuilder.UseStartup<Startup>();
        });

CaptureStartupErrors

false 时,启动期间出错导致主机退出。 true 时,主机在启动期间捕获异常并尝试启动服务器。

:captureStartupErrors
类型:布尔型(true1
默认值:默认为 false,除非应用使用 Kestrel 在 IIS 后方运行,其中默认值是 true
环境变量<PREFIX_>CAPTURESTARTUPERRORS

若要设置此值,使用配置或调用 CaptureStartupErrors

webBuilder.CaptureStartupErrors(true);

DetailedErrors

如果启用,或环境为 Development,应用会捕获详细错误。

:detailedErrors
类型:布尔型(true1
默认值:false
环境变量<PREFIX_>_DETAILEDERRORS

要设置此值,使用配置或调用 UseSetting

webBuilder.UseSetting(WebHostDefaults.DetailedErrorsKey, "true");

HostingStartupAssemblies

承载启动程序集的以分号分隔的字符串在启动时加载。 虽然配置值默认为空字符串,但是承载启动程序集会始终包含应用的程序集。 提供承载启动程序集时,当应用在启动过程中生成其公用服务时将它们添加到应用的程序集加载。

:hostingStartupAssemblies
类型:string
默认值:空字符串
环境变量<PREFIX_>_HOSTINGSTARTUPASSEMBLIES

要设置此值,使用配置或调用 UseSetting

webBuilder.UseSetting(WebHostDefaults.HostingStartupAssembliesKey, "assembly1;assembly2");

HostingStartupExcludeAssemblies

承载启动程序集的以分号分隔的字符串在启动时排除。

键 :hostingStartupExcludeAssemblies
类型:string
默认值:空字符串
环境变量<PREFIX_>_HOSTINGSTARTUPEXCLUDEASSEMBLIES

要设置此值,使用配置或调用 UseSetting

webBuilder.UseSetting(WebHostDefaults.HostingStartupExcludeAssembliesKey, "assembly1;assembly2");

HTTPS_Port

HTTPS 重定向端口。 用于强制实施 HTTPS

密钥:https_port
类型:string
默认:未设置默认值。
环境变量<PREFIX_>HTTPS_PORT

要设置此值,使用配置或调用 UseSetting

webBuilder.UseSetting("https_port", "8080");

PreferHostingUrls

指示主机是否应该侦听使用 IWebHostBuilder 配置的 URL,而不是使用 IServer 实现配置的 URL。

:preferHostingUrls
类型:布尔型(true1
默认值:true
环境变量<PREFIX_>_PREFERHOSTINGURLS

若要设置此值,请使用环境变量或调用 PreferHostingUrls

webBuilder.PreferHostingUrls(false);

PreventHostingStartup

阻止承载启动程序集自动加载,包括应用的程序集所配置的承载启动程序集。 有关详细信息,请参阅 在 ASP.NET Core 中使用承载启动程序集

:preventHostingStartup
类型:布尔型(true1
默认值:false
环境变量<PREFIX_>_PREVENTHOSTINGSTARTUP

若要设置此值,请使用环境变量或调用 UseSetting

webBuilder.UseSetting(WebHostDefaults.PreventHostingStartupKey, "true");

StartupAssembly

要搜索 Startup 类的程序集。

:startupAssembly
类型:string
默认值:应用的程序集
环境变量<PREFIX_>STARTUPASSEMBLY

若要设置此值,请使用环境变量或调用 UseStartup UseStartup 可以采用程序集名称 (string) 或类型 (TStartup)。 如果调用多个 UseStartup 方法,优先选择最后一个方法。

webBuilder.UseStartup("StartupAssemblyName");
webBuilder.UseStartup<Startup>();

URL

IP 地址或主机地址的分号分隔列表,其中包含服务器应针对请求侦听的端口和协议。 例如 http://localhost:123 使用“*”指示服务器应针对请求侦听的使用特定端口和协议(例如 http://*:5000)的 IP 地址或主机名。 协议(http://https://)必须包含每个 URL。 不同的服务器支持的格式有所不同。

:urls
类型:string
默认值http://localhost:5000https://localhost:5001
环境变量<PREFIX_>URLS

若要设置此值,请使用环境变量或调用 UseUrls

webBuilder.UseUrls("http://*:5000;http://localhost:5001;https://hostname:5002");

Kestrel 具有自己的终结点配置 API。 有关详细信息,请参阅 ASP.NET Core 中的 Kestrel Web 服务器实现

WebRoot

应用的静态资产的相对路径。

:webroot
类型:string
默认:默认值为 wwwroot {content root}/wwwroot 的路径必须存在 。 如果该路径不存在,则使用无操作文件提供程序。
环境变量<PREFIX_>WEBROOT

若要设置此值,请使用环境变量或调用 UseWebRoot

webBuilder.UseWebRoot("public");

有关详细信息,请参见:

管理主机生存期

对生成的 IHost 实现调用方法,以启动和停止应用。 这些方法会影响所有在服务容器中注册的 IHostedService 实现。

运行

Run 运行应用并阻止调用线程,直到关闭主机。

RunAsync

RunAsync 运行应用并返回在触发取消令牌或关闭时完成的 Task

RunConsoleAsync

RunConsoleAsync 启用控制台支持、生成和启动主机,以及等待 Ctrl+C/SIGINT 或 SIGTERM 关闭。

Start

Start 同步启动主机。

StartAsync

StartAsync 启动主机并返回在触发取消令牌或关闭时完成的 Task

StartAsync 开始时调用 WaitForStartAsync,在继续之前,会一直等待该操作完成。 它可用于延迟启动,直到外部事件发出信号。

StopAsync

StopAsync 尝试在提供的超时时间内停止主机。

WaitForShutdown

WaitForShutdown 阻止调用线程,直到 IHostLifetime 触发关闭,例如通过 Ctrl+C/SIGINT 或 SIGTERM。

WaitForShutdownAsync

WaitForShutdownAsync 返回在通过给定的令牌和调用 StopAsync 来触发关闭时完成的 Task

外部控件

使用可从外部调用的方法,能够实现对主机生存期的直接控制:

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

ASP.NET Core 应用配置和启动主机。 主机负责应用程序启动和生存期管理。

本文介绍 ASP.NET Core 泛型主机 (HostBuilder),该主机用于无法处理 HTTP 请求的应用。

泛型主机的用途是将 HTTP 管道从 Web 主机 API 中分离出来,从而启用更多的主机方案。 基于泛型主机的消息、后台任务和其他非 HTTP 工作负载可从横切功能(如配置、依赖关系注入 [DI] 和日志记录)中受益。

泛型主机是 ASP.NET Core 2.1 中的新增功能,不适用于 Web 承载方案。 对于 Web 承载方案,请使用 Web 主机 泛型主机将在未来版本中替换 Web 主机,并在 HTTP 和非 HTTP 方案中充当主要的主机 API。

查看或下载示例代码如何下载

Visual Studio Code 中运行示例应用时,请使用外部或集成终端 。 请勿在 internalConsole 中运行示例。

在 Visual Studio Code 中设置控制台:

  1. 打开 .vscode/launch.json 文件 。
  2. 在 .NET Core 启动(控制台)配置中,找到控制台条目 。 将值设置为 externalTerminalintegratedTerminal

介绍

通用主机库位于 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.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``StagingProduction 值不区分大小写。

var host = new HostBuilder()
    .UseEnvironment(EnvironmentName.Development)

ConfigureHostConfiguration

ConfigureHostConfiguration 使用 IConfigurationBuilder 来为主机创建 IConfiguration 主机配置用于初始化 IHostingEnvironment,以供在应用的构建过程中使用。

可多次调用 ConfigureHostConfiguration,并得到累计结果。 主机使用上一次在一个给定键上设置值的选项。

默认情况下不包括提供程序。 必须在 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"
}

可以通过 applicationNamecontentRoot 键提供其他配置。

示例 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>

备注

配置扩展方法(如 AddJsonFileAddEnvironmentVariables)需要其他 NuGet 包(如 Microsoft.Extensions.Configuration.JsonMicrosoft.Extensions.Configuration.EnvironmentVariables)。 除非应用使用 Microsoft.AspNetCore.App 元包,否则除了核心 Microsoft.Extensions.Configuration 包之外,还必须将这些包添加到项目。 有关详细信息,请参阅 ASP.NET Core 中的配置

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 解除阻止 RunAsyncWaitForShutdownAsync 等扩展。 Microsoft.Extensions.Hosting.Internal.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 触发,例如 Microsoft.Extensions.Hosting.Internal.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();
    }
}

其他资源