Skip to main content

.Net Core中的Host

分类:  Asp.net Core入门 标签:  #Asp.Net core基础 #基础 #Web 发布于: 2023-06-04 20:35:11

.Net Core.Net 5 以上有一个非常好的概念就是:Host, 中文可以翻译为主机,但是不够贴切,所以还是以Host比较好。Host作为一个程序的框架,非常方便大家用于设计多种类型的应用,微软也有很多产品都是基于这个模型来设计的,例如我们的ASP.net Core框架,以及Azure Funciton都是很优秀的代表。

那么怎么定义Host的概念呢?

Host就是指封装了一个应用的所有资源的对象,同时它也是一个程序框架,帮助大家快速的使用.Net Core.Net进行应用开发,同时它还管理了应用的各种依赖资源以及应用的生命周期:

  • 提供了依赖注入支持
  • 支持日志
  • 支持配置
  • IHostedService的实现,用于实现各种服务。例如WebHost就是一种实现了HTTP Server的服务。后面我们学习到Server的时候再回看一下这个概念。

设置一个Host

一般的步骤就是配置,创建,然后运行一个Host, 主要使用的到方法如下:

  • 调用CreateHostBuilder方法创建和配置一个IHostBuilder对象。
  • 调用IHostBuilder对象的Build方法和Run方法,就可以运行一个Host了。

下面来看两个例子:

例子1: 是为了Web 应用创建的一个Host:

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

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

例子2: 创建一个非Web 应用的Host:

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

创建web应用和非web应用中最大的区别在于,在调用了CreateDefaultBuilder之后,如果再调用ConfigureWebHostDefaults(IHostBuilder, IWebHostBuilder)的扩展方法继续配置作为Web 应用需要的一些配置。

默认配置

当我们调用CreateDefaultBuilder的时候:

  • 设置Content root到当前的目录,当前目录由GetCurrentDirectory来返回。
  • 载入Host的配置:
    • 从环境变量中载入Host的配置,变量前缀以DOTNET_开始。
    • 从命令行参数中读入Host的配置。
  • 载入应用配置
    • appsettings.json
    • appsettings.{Environment}.json
    • 当用户是在Development环境时载入User secrets
    • 从环境变量中载入配置, DOTNET_前缀。
    • 从命令行中载入参数。
  • 添加日志支持,提供如下的日志提供者:
    • Console
    • Debug
    • EventSource
    • EventLog(仅仅支持Windows)
  • 当应用处于Development环境时,启用Scope ValidationDependency validation

当调用ConfigureWebHostDefaults方法:

  • 从环境变量中载入前缀为ASPNETCORE_的host配置。
  • 设置Kestrel为Web服务其,并且通过应用host的配置开始配置它。
  • 添加Host Filtering 中间件。
  • 如果指定了变量ASPNETCORE_FORWARDEDHEADERS_ENABLED, 那么回启动forwarded headers中间件。
  • 启用IIS集成。

框架提供的服务

框架会自动注册下列服务:

  • IHostApplicationLifetime
  • IHostLifetime
  • IHostEnvironment/IWebHostEnvironment

IHostApplicationLifetime

这个服务提供三个事件和一个属性供那些实现了Host的一些状态变化时候的订阅和定制,可以参考一下如下的代码:

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

这个接口实现和Host启动和停止的接口,默认是Microsoft.Extensions.Hosting.Internal.ConsoleLifetime的console默认实现。

IHostEnvironment

注册这个服务到容器里主要提供如下的信息:

  • ApplicationName
  • EnvironmentName
  • ContentRootPath

另外如果是Web, web app实现了IWebHostEnviroment, 添加了WebRootPath的设置。

Host配置

Host的配置使用IHostEnvironment的属性来表示。

同时Host的配置有两个地方都可以配置,每个配置方法都可以调用多次。

  • HostBuilder.ConfigureHostConfiguration(Action<Microsoft.Extensions.Configuration.IConfigurationBuilder> configureDelegate)
  • HostBuilder.ConfigureAppConfiguration(Action<HostBuilderContext,IConfigurationBuilder>)

不过需要注意的是,第二个会替代第一个的配置,如果同样的Key

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

应用配置

应用的配置就在这里运行:
HostBuilder.ConfigureAppConfiguration(Action<HostBuilderContext,IConfigurationBuilder>)

至于有哪些配置项,您可以参考这里:https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/generic-host?view=aspnetcore-5.0#settings-for-all-app-types