asp.net core 系列 17 通用主机 IHostBuilder
一.概述
asp.net core 通用主机 (hostbuilder),该主机对于托管不处理 http 请求的应用非常有用。通用主机的目标是将 http 管道从 web 主机 api 中分离出来,从而启用更多的主机方案。 基于通用主机的消息、后台任务和其他非 http 工作负载可从横切功能(如配置、依赖关系注入 [di] 和日志记录)中受益。通用主机是 asp.net core 2.1 中的新增功能,不适用于 web 承载方案。通用主机正处于开发阶段,用于在未来版本中替换 web 主机,并在 http 和非 http 方案中充当主要的主机 api。
通用主机库位于 microsoft.extensions.hosting 命名空间中,而web主机库位于microsoft.aspnetcore.hosting命令空间中。
pm> install-package microsoft.aspnetcore.hosting.abstractions -version 2.2.0
1.1 设置主机
ihostbuilder 是供库和应用初始化、生成和运行主机的主要组件。(官方文档中main方法是使用的异步,但本人vs程序启动时提示找不到mian方法,只好改成了同步) 。
public static void main(string[] args) { var host = new hostbuilder() .build(); host.run(); }
1.2 默认服务
在主机初始化期间注册以下服务:
环境 (ihostingenvironment)
hostbuildercontext
配置 (iconfiguration)
iapplicationlifetime (applicationlifetime)
ihostlifetime (consolelifetime)
ihost
选项 (addoptions)
日志记录 (addlogging)
1.3 主机配置 configurehostconfiguration
主机配置的创建方式如下:
调用 ihostbuilder 上的扩展方法以设置“内容根”和“环境”。
从 configurehostconfiguration 中的配置提供程序读取配置。
(1) configurehostconfiguration 主机配置
通用主机配置与web主机配置还是有些区别,在通用主机中有configurehostconfiguration用来配置主机。主机配置用于初始化 ihostingenvironment,以供在应用的构建过程中使用。可多次调用 configurehostconfiguration
,并得到累计结果。必须在 configurehostconfiguration
中显式指定应用所需的任何配置提供程序,包括:
1)文件配置(例如,来自 hostsettings.json 文件)。
2)环境变量配置。
3)命令行参数配置。
4)任何其他所需的配置提供程序。
通过使用 setbasepath 指定应用的基本路径,然后调用其中一个文件配置提供程序,可以启用主机的文件配置。
(2) addenvironmentvariables 环境变量
要添加主机的环境变量配置,请在主机生成器上调用 addenvironmentvariables。 示例应用使用前缀 prefix_
。 当系统读取环境变量时,便会删除前缀。 配置示例应用的主机后,prefix_environment
的环境变量值就变成 environment
密钥的主机配置值。
(3) addcommandline 命令行参数
通过 dotnet run
运行应用 指定参数时,通过调用 addcommandline 可添加命令行配置。
1.4 应用配置 configureappconfiguration
调用 configureappconfiguration 创建应用配置,在web主机中也有介绍。这里就不再说明。 主机配置和应用配置都可以做配置使用,主机配置重点在主机环境的配置(ihostingenvironment)。
1.5 configureservices
configureservices 将服务添加到应用的依赖关系注入容器。 可多次调用 configureservices,并得到累计结果。这个在web主机中常用。 值得注意的是:除了三种注入的实例生命周期(asp.net core 系列 4 注入服务的生存期)。还可以注入thostedservice类型服务,专门用于做后台服务的。
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>(); })
1.6 iapplicationlifetime 接口
iapplicationlifetime接口在上篇介绍web主机进有讲过,这里不在具体介绍。下面会有代码演示,实现一个ihostedservice类型服务,在服务中用于注册事件。
二. 完整示例
使用通用主机来演示一个后台服务。使用控制台做宿主,后台服务定时每隔5秒执行一次。该演示包括主机配置、应用配置、服务容器注入、日志配置。还包括注入二个ihostedservice类型的服务。其中timedhostedservice类用于做后台定时服务,lifetimeeventshostedservice类注入服务iapplicationlifetime事件,监听服务运行状态。
完整示例github地址:
public class program { /// <summary> /// 使用控制台做承载的后台服务 /// </summary> /// <param name="args"></param> public static void main(string[] args) { var host = new hostbuilder() .configurehostconfiguration(confighost => { confighost.setbasepath(directory.getcurrentdirectory()); confighost.addjsonfile("hostsettings.json", optional: true); confighost.addenvironmentvariables(prefix: "prefix_"); confighost.addcommandline(args); }) .configureappconfiguration((hostcontext, configapp) => { configapp.addjsonfile("appsettings.json", optional: true); configapp.addjsonfile( $"appsettings.{hostcontext.hostingenvironment.environmentname}.json", optional: true); configapp.addenvironmentvariables(prefix: "prefix_"); configapp.addcommandline(args); }) .configureservices((hostcontext, services) => { //注册后台普通服务 // services.addsingleton<ijobtimeservice, jobtimeservice>(); //注册后台thostedservice类型服务 services.addhostedservice<lifetimeeventshostedservice>(); services.addhostedservice<timedhostedservice>(); }) .configurelogging((hostcontext, configlogging) => { configlogging.addconsole(); configlogging.adddebug(); }) .useconsolelifetime() .build(); //实例化注入的普通服务 // ijobtimeservice job = host.services.getrequiredservice<ijobtimeservice>(); // job.time(); host.run(); } }
/// <summary> ///监听服务运行状态 /// </summary> 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 } }
/// <summary> /// 后台定时服务 /// </summary> internal class timedhostedservice : ihostedservice, idisposable { private readonly ilogger _logger; private timer _timer; public timedhostedservice(ilogger<timedhostedservice> logger) { _logger = logger; } public task startasync(cancellationtoken cancellationtoken) { _logger.loginformation("timed background service is starting."); _timer = new timer(dowork, null, timespan.zero, timespan.fromseconds(5)); return task.completedtask; } /// <summary> /// 每隔5秒执行一次 /// </summary> /// <param name="state"></param> private void dowork(object state) { _logger.loginformation("timed background service is working."); } public task stopasync(cancellationtoken cancellationtoken) { _logger.loginformation("timed background service is stopping."); _timer?.change(timeout.infinite, 0); return task.completedtask; } public void dispose() { _timer?.dispose(); } }
-- hostsettings.json文件 { "environment": "development" }
参考文献:
官方文档:asp.net core 通用主机
推荐阅读
-
asp.net core 3.x 通用主机是如何承载asp.net core的-上
-
asp.net core 系列 17 通用主机 IHostBuilder
-
asp.net core 3.x 通用主机原理及使用
-
(16)ASP.NET Core 通用主机(HostBuilder)
-
asp.net core 系列 16 Web主机 IWebHostBuilder
-
asp.net core 系列 17 通用主机 IHostBuilder
-
asp.net core 3.x 通用主机是如何承载asp.net core的-上
-
asp.net core 3.x 通用主机原理及使用
-
(16)ASP.NET Core 通用主机(HostBuilder)
-
asp.net core 系列 16 Web主机 IWebHostBuilder