.Net Host提供的服务和接口
分类: .Net技术 ◆ 标签: #基础 #.Net #.Net Host ◆ 发布于: 2023-06-15 15:46:11
我们前面一篇文章里学习了怎么快速的设置一个Host, 并且介绍了在设置Host的每一步里每个方法需要完成哪些配置或者动作,我们这一章来学习.Net基于Host模型提供了哪些服务和接口,这些服务和接口是如何方便用户使用的。
Host提供的服务
我们前面介绍了当设置一个Host时会自动创建一个依赖注入容器,同时作为一个框架也会随着容器的创建并自动注入一相应的服务,主要有如下的服务:
IHostApplicationLifeTimeIHostLifetimeIHostEnvironment
IHostApplicationLifetime
实现了这个接口的服务主要用于给用户的应用一个和Host的started, stopping, stopped几个事件进行交互,当Host里的应用发生这些事件时,用户应用监听这些事件并完成相应的动作。
我们使用如下的例子来看一下这个服务的用法:
dotnet new worker -o WorkerDemo1
cd WorkerDemo1
code .
需要注意的是我们这里使用了.Net自带的模板worker创建了一个基于worker的示例应用,使用VS Code打开了应用目录之后,编辑文件Worker.cs, 使用如下的内容替换:
namespace WorkerDemo1; public class Worker : IHostedService { private readonly ILogger<Worker> _logger; public Worker(ILogger<Worker> logger, IHostApplicationLifetime applicationLifetime ) { _logger = logger; applicationLifetime.ApplicationStarted.Register(OnStarted); applicationLifetime.ApplicationStopping.Register(OnStopping); applicationLifetime.ApplicationStopped.Register(OnStopped); } public async Task StartAsync(CancellationToken stoppingToken) { _logger.LogInformation("1. StartAsync has been called."); await Task.CompletedTask; } public async Task StopAsync(CancellationToken cancellationToken) { _logger.LogInformation("4. StopAsync has been called. "); await Task.CompletedTask; } private void OnStarted() { _logger.LogInformation("2. OnStarted has been called."); } private void OnStopping() { _logger.LogInformation("3. OnStopping has been called."); } private void OnStopped() { _logger.LogInformation("5. OnStopped has been called."); } }
从代码里可以我们看到我们通过Worker类的构造函数注入了IHostApplicationLifetime示例,然后通过该示例的属性监听了基于Host的程序启动,关闭事件,并作出相应的反应。
保存该文件之后,在目录下运行dotnet run, 等程序启动后,观察输出,然后按ctrl+c中断应用,观察输出:
Microsoft Windows [Version 10.0.22000.556]
(c) Microsoft Corporation. All rights reserved.
正在生成...
info: WorkerDemo1.Worker[0]
1. StartAsync has been called.
info: WorkerDemo1.Worker[0]
2. OnStarted has been called.
info: Microsoft.Hosting.Lifetime[0]
Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
Hosting environment: Development
info: Microsoft.Hosting.Lifetime[0]
Content root path: D:\MyProjects\DotNetLearning\WorkerDemo1
info: WorkerDemo1.Worker[0]
3. OnStopping has been called.
info: Microsoft.Hosting.Lifetime[0]
Application is shutting down...
info: WorkerDemo1.Worker[0]
4. StopAsync has been called.
info: WorkerDemo1.Worker[0]
5. OnStopped has been called.
可以看到通过实现IHostService来作为切入点开发自己的应用,基于.Net Host的Asp.net core也是从实现IHostService开始。
IHostLifetime
Host模型通过提供接口IHostLifetime实现,用于实现Host启动或者停止。默认的实现是Microsoft.Extensions.Hosting.Internal.ConsoleLifetime。
用户通过实现接口IHostedService向Host注入自己的代码,Host在启动之后,会按照通过扩展方法AddHostedService<>注册的IHostedService顺序依次启动用户的Service。 Host启动之后一般在如下几种情况下会停止运行:
- 如果用户在主线程里没有运行
Host的Run或者WaitForShutdown方法,那么Host会随着Main方法的结束而自然结束。 - 基于
Host的应用崩溃。 - 被强制使用信号
SIGKILL(CTRL+Z)强行停止了。
自从.Net 6+, 默认使用了ConsoleLifetime实现,新增了如下几种方式可以停止Host以及Host启用的应用:
SIGINT信号(CTRL+C)SIGQUIT信号(CTRL+breakon windows,CTRL+\on Unix)SIGTERM信号(由其他应用发出信号,例如使用kill发送。)
由于在.Net 6+上完全支持POSIX信号,在应用中不要使用Enviroment.exit来主动退出应用,而应该使用接口IHostApplicationLifetime.StopApplication方法来停止应用。
基于IHostLifetime接口的Host如何实现Host shutdown的流程:
可以仔细的看一下官方网站给出来的图:
普通用户可以不用详细了解该过程,但是如果想深入学习和理解Host模型,可以仔细研究一下这个过程。
IHostEnvironment
注入该服务提供如下的信息:
IHostEnvironment.ApplicationNameIHostEnvironment.ContentRootFileProviderIHostEnvironment.ContentRootPathIHostEnvironment.EnvironmentName
Host的配置
我们之前讨论过说在静态类Host上调用CreateDefaultBuilder会自动从环境变量和命令行中读入Host的配置,我们还可以在IHostBuilder上多次调用ConfigureHostConfiguration来配置Host, 例如:
static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureHostConfiguration(configHost => { configHost.SetBasePath(Directory.GetCurrentDirectory()); configHost.AddJsonFile("hostsettings.json", optional: true); configHost.AddEnvironmentVariables(prefix: "PREFIX_"); configHost.AddCommandLine(args); });
configHost这里是一个IHostBuilder的变量,在这个实例变量上你可以调用多个方法用于配置Host。
应用的配置
如果想在代码里配置应用,您可以在IHostBuilder上调用方法ConfigureAppConfiguration来配置应用。
例如:
.ConfigureAppConfiguration( appConfig => { } )
你会发现appConfig是接口IConfigurationBuilder的实例。
使用Host配置Web应用
我们前面讨论的都是基于.Net的通用型Host, 如果我们要实现可以运行Web应用的Host,我们之前也讨论过,有两种方式,第一种是从.Net6开始的基于WebApplicationBuilder和WebApplicationi,还有一种是在Generic Host上配置基于web的配置,如下的代码:
public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); };
也即在IHostBuilder上继续调用方法ConfigureWebHostDefaults
ConfigureWebHostDefault方法做了哪些事?您可以参考我们上一章的说明。
基于Web的host提供了哪些内容?
我们之前讨论的都是基于Generic Host, 我们再来讨论一下如果我们是为了一个Web应用设置的Host, 提供了多少其他的内容:
ApplicationNameContentRootEnvironmentNameShutdownTimeout
等等。
关于这些您可以参考一下Host的源码:https://github.com/dotnet/runtime/blob/main/src/libraries/Microsoft.Extensions.Hosting/src/Host.cs