.Net Host提供的服务和接口
分类: .Net技术 ◆ 标签: #基础 #.Net #.Net Host ◆ 发布于: 2023-06-15 15:46:11

我们前面一篇文章里学习了怎么快速的设置一个Host
, 并且介绍了在设置Host
的每一步里每个方法需要完成哪些配置或者动作,我们这一章来学习.Net
基于Host
模型提供了哪些服务和接口,这些服务和接口是如何方便用户使用的。
Host
提供的服务
我们前面介绍了当设置一个Host
时会自动创建一个依赖注入容器,同时作为一个框架也会随着容器的创建并自动注入一相应的服务,主要有如下的服务:
IHostApplicationLifeTime
IHostLifetime
IHostEnvironment
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+break
on windows,CTRL+\
on Unix)SIGTERM
信号(由其他应用发出信号,例如使用kill
发送。)
由于在.Net 6+
上完全支持POSIX
信号,在应用中不要使用Enviroment.exit
来主动退出应用,而应该使用接口IHostApplicationLifetime.StopApplication
方法来停止应用。
基于IHostLifetime
接口的Host如何实现Host shutdown
的流程:
可以仔细的看一下官方网站给出来的图:
普通用户可以不用详细了解该过程,但是如果想深入学习和理解Host
模型,可以仔细研究一下这个过程。
IHostEnvironment
注入该服务提供如下的信息:
IHostEnvironment.ApplicationName
IHostEnvironment.ContentRootFileProvider
IHostEnvironment.ContentRootPath
IHostEnvironment.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, 提供了多少其他的内容:
ApplicationName
ContentRoot
EnvironmentName
ShutdownTimeout
等等。
关于这些您可以参考一下Host
的源码:https://github.com/dotnet/runtime/blob/main/src/libraries/Microsoft.Extensions.Hosting/src/Host.cs