(16)ASP.NET Core 通用主机(HostBuilder)
1.前言
asp.net core应用程序可以配置和启动主机(host)。主机负责应用程序启动和生命周期管理。通用主机用于无法处理http请求的应用程序。通用主机的用途是将http管道从web主机api中分离出来,从而启用更多的主机方案。 基于通用主机的消息、后台任务和其他非http工作负载可从横切功能(如配置、依赖关系注入[di]和日志记录)中受益。通用主机是asp.net core 2.1中的新增功能,不适用于web承载方案。对于web承载方案,请使用web主机。通用主机将在未来版本中替换web主机,并在http和非http方案中充当主要的主机api。
2.介绍
ihostedservice是执行代码的入口点。每个ihostedservice实现都按照configureservices中服务注册的顺序执行。主机启动时,每个ihostedservice上都会调用startasync,主机正常关闭时,以反向注册顺序调用stopasync。
3.设置主机
ihostbuilder是供库和应用程序初始化、生成和运行主机的主要组件:
public static async task main(string[] args) { var host = new hostbuilder().build(); await host.runasync(); }
4.选项
hostoptions配置ihost的选项。
4.1关闭超时值
shutdowntimeout设置stopasync的超时值。默认值为5秒。program.main中的以下选项配置将默认值为5秒的关闭超时值增加至20秒:
var host = new hostbuilder().configureservices((hostcontext, services) => { services.configure<hostoptions>(option => { option.shutdowntimeout = system.timespan.fromseconds(20); }); }) .build();
5.默认服务
在主机初始化期间注册以下服务:
●环境 (ihostingenvironment)
●hostbuildercontext
●配置 (iconfiguration)
●iapplicationlifetime (applicationlifetime)
●ihostlifetime (consolelifetime)
●ihost
●选项 (addoptions)
●日志记录 (addlogging)
6.主机配置
主机配置的创建方式如下:
●调用ihostbuilder上的扩展方法以设置“内容根”和“环境”。
●从configurehostconfiguration中的配置提供应用程序读取配置。
●应用程序键(名称)、内容根、环境配置方式我就不多说了,跟上一篇web主机配置是一样的。
6.1configurehostconfiguration
configurehostconfiguration使用iconfigurationbuilder来为主机创建iconfiguration。主机配置用于初始化ihostingenvironment,以供在应用程序的构建过程中使用。可多次调用configurehostconfiguration,并得到累计结果。必须在configurehostconfiguration中显式指定应用程序所需的任何配置提供自身,包括:
●文件配置(例如,来自hostsettings.json文件)。
●环境变量配置。
●命令行参数配置。
●任何其他所需的配置提供程序。
通过使用setbasepath指定应用程序的基本路径,然后调用其中一个文件配置提供应用程序,可以启用主机的文件配置。示例应用使用json文件hostsettings.json,并调用addjsonfile来使用文件的主机配置设置。要添加主机的环境变量配置,请在主机生成器上调用 addenvironmentvariables。addenvironmentvariables接受用户定义的前缀(可选)。示例应用程序使用前缀prefix_。当系统读取环境变量时,便会删除前缀。配置示例应用程序的主机后,prefix_environment的环境变量值就变成environment密钥的主机配置值。示例hostbuilder配置使用configurehostconfiguration:
var host = new hostbuilder().configurehostconfiguration(confighost => { confighost.setbasepath(directory.getcurrentdirectory()); confighost.addjsonfile("hostsettings.json", optional: true); confighost.addenvironmentvariables(prefix: "prefix_"); confighost.addcommandline(args); })
6.2configureappconfiguration
通过在ihostbuilder实现上调用configureappconfiguration创建应用程序配置。configureappconfiguration使用iconfigurationbuilder来为应用程序创建iconfiguration。可多次调用configureappconfiguration,并得到累计结果。应用程序使用上一次在一个给定键上设置值的选项。hostbuildercontext.configuration中提供configureappconfiguration创建的配置,以供进行后续操作和在services中使用。应用程序配置会自动接收configurehostconfiguration提供的主机配置。示例应用配置使用configureappconfiguration:
var host = new hostbuilder().configureappconfiguration((hostcontext, configapp) => { configapp.setbasepath(directory.getcurrentdirectory()); configapp.addjsonfile("appsettings.json", optional: true); configapp.addjsonfile( $"appsettings.{hostcontext.hostingenvironment.environmentname}.json", optional: true); configapp.addenvironmentvariables(prefix: "prefix_"); configapp.addcommandline(args); })
6.3configureservices
configureservices将服务添加到应用程序的依赖关系注入容器。可多次调用configureservices,并得到累计结果。托管服务是一个类,具有实现ihostedservice接口的后台任务逻辑。示例应用程序使用addhostedservice扩展方法向自身添加生命周期事件 lifetimeeventshostedservice和定时后台任务timedhostedservice服务:
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>(); })
6.4configurelogging
configurelogging添加了一个委托来配置提供的iloggingbuilder。可以利用相加结果多次调用 configurelogging。
var host = new hostbuilder().configurelogging((hostcontext, configlogging) => { configlogging.addconsole(); configlogging.adddebug(); })
6.4.1useconsolelifetime
useconsolelifetime侦听ctrl+c/sigint或sigterm并调用stopapplication来启动关闭进程。useconsolelifetime解除阻止runasync和waitforshutdownasync等扩展。consolelifetime预注册为默认生命周期实现,使用注册的最后一个生命周期。
var host = new hostbuilder().useconsolelifetime()
7.容器配置
主机可以接受iserviceproviderfactory<tcontainerbuilder>。提供工厂不属于di容器注册,而是用于创建具体di容器的主机内部函数。useserviceproviderfactory(iserviceproviderfactory<tcontainerbuilder>)重写用于创建应用程序的服务提供程序的默认工厂。configurecontainer方法托管自定义容器配置。configurecontainer提供在基础主机api的基础之上配置容器的强类型体验。可以利用相加结果多次调用configurecontainer。
为应用程序创建服务容器并提供服务容器工厂:
public class generichostsample { internal class servicecontainerfactory : iserviceproviderfactory<servicecontainer> { public servicecontainer createbuilder(iservicecollection services) { return new servicecontainer(); } public iserviceprovider createserviceprovider(servicecontainer containerbuilder) { throw new notimplementedexception(); } } }
使用该工厂并为应用程序配置自定义服务容器:
var host = new hostbuilder().useserviceproviderfactory<servicecontainer>(new servicecontainerfactory()) .configurecontainer<servicecontainer>((hostcontext, container) =>{ })
8.扩展性
在ihostbuilder上使用扩展方法实现主机扩展性。应用程序建立usehostedservice扩展方法,以注册在t中传递的托管服务:
public static class extensions { public static ihostbuilder usehostedservice<t>(this ihostbuilder hostbuilder) where t : class, ihostedservice, idisposable { return hostbuilder.configureservices(services => services.addhostedservice<t>()); } }
9.管理主机
ihost实现负责启动和停止由服务容器中注册的ihostedservice实现。
9.1run
run运行应用程序并阻止调用线程,直到关闭主机:
public class program { public void main(string[] args) { var host = new hostbuilder().build(); host.run(); } }
9.2runasync
runasync运行应用程序并返回在触发取消令牌或关闭时完成的task:
public class program { public static async task main(string[] args) { var host = new hostbuilder().build(); await host.runasync(); } }
9.3runconsoleasync
runconsoleasync启用控制台、生成和启动主机,以及等待ctrl+c/sigint或sigterm关闭。
public class program { public static async task main(string[] args) { var hostbuilder = new hostbuilder(); await hostbuilder.runconsoleasync(); } }
9.4start和stopasync
start同步启动主机。stopasync尝试在提供的超时时间内停止主机。
public class program { public static async task main(string[] args) { var host = new hostbuilder().build(); using (host) { host.start(); await host.stopasync(timespan.fromseconds(5)); } } }
9.5startasync和stopasync
startasync启动应用程序。stopasync停止应用程序。
public class program { public static async task main(string[] args) { var host = new hostbuilder().build(); using (host) { await host.startasync(); await host.stopasync(); } } }
9.6waitforshutdown
waitforshutdown通过ihostlifetime触发,例如consolelifetime(侦听ctrl+c/sigint或sigterm)。waitforshutdown调用stopasync。
public class program { public void main(string[] args) { var host = new hostbuilder().build(); using (host) { host.start(); host.waitforshutdown(); } } }
9.7waitforshutdownasync
waitforshutdownasync返回在通过给定的令牌和调用stopasync来触发关闭时完成的task。
public class program { public static async task main(string[] args) { var host = new hostbuilder().build(); using (host) { await host.startasync(); await host.waitforshutdownasync(); } } }
9.8external control(外部控件)
public class program { private ihost _host; public program() { _host = new hostbuilder() .build(); } public async task startasync() { _host.startasync(); } public async task stopasync() { using (_host) { await _host.stopasync(timespan.fromseconds(5)); } } }
在startasync开始时调用waitforstartasync,在继续之前,会一直等待该操作完成。它可用于延迟启动,直到外部事件发出信号。
10.ihostingenvironment、iapplicationlifetime接口
该两个接口类型跟上一篇web主机ihostingenvironment、iapplicationlifetime接口类型是一样的,详情就不在这多讲了,想要了解的请移步到上一篇web主机文章。
参考文献:
asp.net core 通用主机
推荐阅读
-
ASP.NET Core Web 应用程序开发期间部署到IIS自定义主机域名并附加到进程调试
-
asp.net core 3.x 通用主机是如何承载asp.net core的-上
-
ASP.NET Core扩展库之Http通用扩展库的使用详解
-
asp.net core 系列 17 通用主机 IHostBuilder
-
基于ASP.Net Core开发的一套通用后台框架
-
(15)ASP.NET Core Web主机(IWebHostBuilder)
-
asp.net core 3.x 通用主机原理及使用
-
ASP.NET Core主机地址过滤HostFiltering
-
(16)ASP.NET Core 通用主机(HostBuilder)
-
基于ASP.Net Core开发一套通用后台框架记录-(总述)