# 模块二 基础巩固 Host

## 2.2.4 核心模块--Host <a href="#id-224-he-xin-mo-kuai-host" id="id-224-he-xin-mo-kuai-host"></a>

* 什么是 Host
* Host 的默认配置做了哪些事情
* 框架提供的服务
* HostedService 后台服务

ASP.NET Core Web 主机：<https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/host/web-host?view=aspnetcore-5.0>

### 什么是 Host <a href="#shen-me-shi-host" id="shen-me-shi-host"></a>

主机是封装应用资源的对象，例如：

* 依赖关系注入（DI）
* Logging
* Configuration
* IHostedService 实现

对应 Program.cs 中的 host.Run();

可以在主机启动前通过 CreateHostBuilder 进行配置

### Host 的默认配置做了哪些事情 <a href="#host-de-mo-ren-pei-zhi-zuo-le-na-xie-shi-qing" id="host-de-mo-ren-pei-zhi-zuo-le-na-xie-shi-qing"></a>

CreateHostBuilder 方法

* 将内容根目录设置为由 GetCurrentDirectory 返回的路径
* 加载主机配置（前缀为 DOTNET\_ 的环境变量；命令行参数）
* 加载应用配置（appsettings.json; appsettings.{Environment}.json; 密钥管理器；环境变量；命令行参数）
* 添加日志记录程序（控制台；调试；EventSource；EventLog）
* 当环境为”开发“时，启用范围验证和依赖关系验证
* ConfigureWebHostDefaults（asp.net core 需要）

```
// 内容根目录
var root = hostingContext.HostingEnvironment.ContentRootPath;

// 环境
var envName = hostingContext.HostingEnvironment.EnvironmentName;
```

ConfigureWebHostDefaults 方法

* 从前缀为 ASPNETCORE\_ 的环境变量加载主机配置
* 使用应用的托管配置提供程序将 Kestrel 服务器设置为 web 服务器并对其进行配置
* 添加主机筛选中间件
* 如果 ASPNETCORE\_FORWARDEDHEADERS\_ENABLED 等于 true，则添加转接头中间件
* 支持 IIS 集成

### 框架提供的服务 <a href="#kuang-jia-ti-gong-de-fu-wu" id="kuang-jia-ti-gong-de-fu-wu"></a>

* IHostApplicationLifetime
* IHostLifetime
* IHostEnvironment / IWebHostEnvironment

#### IHostApplicationLifetime <a href="#ihostapplicationlifetime" id="ihostapplicationlifetime"></a>

Program.cs

```
var applicationLifetime = host.Services.GetRequiredService<IHostApplicationLifetime>();

applicationLifetime.ApplicationStarted.Register((() =>
{
    Console.WriteLine("Application Started");
}));

applicationLifetime.ApplicationStopping.Register((() =>
{
    Console.WriteLine("Application Stopping");
}));

applicationLifetime.ApplicationStopped.Register((() =>
{
    Console.WriteLine("Application Stopped");
}));
```

用于监控 Host 主机的启动，停止

#### IHostLifetime <a href="#ihostlifetime" id="ihostlifetime"></a>

同样的监听

#### IHostEnvironment / IWebHostEnvironment <a href="#ihostenvironment--iwebhostenvironment" id="ihostenvironment--iwebhostenvironment"></a>

将 IHostEnvironment 服务注册到一个类，获取以下设置的信息

* ApplicationName
* EnvironmentName
* ContentRootPath

### HostedService 后台服务 <a href="#hostedservice-hou-tai-fu-wu" id="hostedservice-hou-tai-fu-wu"></a>

新建 MyHostedService.cs

```
namespace HelloApi.Services
{
    public class MyHostedService : IHostedService
    {
        public Task StartAsync(CancellationToken cancellationToken)
        {
            throw new NotImplementedException();
        }

        public Task StopAsync(CancellationToken cancellationToken)
        {
            throw new NotImplementedException();
        }
    }
}
```

在 IHostedService 的基础之上，asp .net core 还提供了另一个封装 BackgroundService

```
public class MyBackgroundService : BackgroundService
{
    protected override Task ExecuteAsync(CancellationToken stoppingToken)
    {
        throw new NotImplementedException();
    }
}
```

在 StopAsync 之前会通过 CancellationToken 通知，执行一些操作

```
public class MyBackgroundService : BackgroundService
{
    private readonly ILogger<MyBackgroundService> _logger;

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

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        // 只要不停止就一直执行
        while (!stoppingToken.IsCancellationRequested)
        {
            _logger.LogInformation("date:{0}", DateTime.Now);
            await Task.Delay(1000, stoppingToken);
        }
    }
}
```

在 Startup.cs 中注入

```
services.AddHostedService<MyBackgroundService>();
```

启动程序，控制台不断输出时间

请求接口也可以正常访问

asp .net core 通过这样一种 HostedService 的方式将后台常驻服务与 web api 的请求同时放到一个托管基类

### GitHub源码链接： <a href="#github-yuan-ma-lian-jie" id="github-yuan-ma-lian-jie"></a>

<https://github.com/MingsonZheng/ArchitectTrainingCamp/tree/main/HelloApi>
