快速了解如何在.NETCORE中使用Generic-Host建立主机
.netcore 中的 generic host
本文以自己在工作中学习和使用.net core generic-host 作一个总结。
前言
在创建的aspnetcore项目中,我们可以在main()
中看见,我们通过iwebhostbuild
创建了一个iwebhost
,而微软提供了webhost.createdefaultbuilder(args)
来帮助我们更轻松得创建webhost
。
常常我们的需求不需要创建web项目,比如后台任务,那么我们如何像使用aspnetcore一样创建控制台项目。
如何在控制台程序中创建主机
通过dotnet new console
创建一个控制台项目
通过nuget添加以下包
microsoft.extensions.hosting
首先,我们看下ihostbuilder
接口里的方法
public interface ihostbuilder { ihost build(); ihostbuilder configureappconfiguration(action<hostbuildercontext, iconfigurationbuilder> configuredelegate); ihostbuilder configurecontainer<tcontainerbuilder>(action<hostbuildercontext, tcontainerbuilder> configuredelegate); ihostbuilder configurehostconfiguration(action<iconfigurationbuilder> configuredelegate); ihostbuilder configureservices(action<hostbuildercontext, iservicecollection> configuredelegate); ihostbuilder useserviceproviderfactory<tcontainerbuilder>(iserviceproviderfactory<tcontainerbuilder> factory); }
configureappconfiguration()
可以配置应用的一些配置,如环境变量等等
configurecontainer()
& useserviceproviderfactory()
可以配置替换默认的依赖注入的组件,比如替换成autofac
configurehostconfiguration()
可以配置iconfiguration
configureservices()
可以注入服务
接下去,通过以下代码,我们可以构建一个简单的主机。
static void main(string[] args) { createdefaulthost(args).build().run(); }static ihostbuilder createdefaulthost(string[] args) => new hostbuilder() .configurehostconfiguration(builder => { //todo }) .configureappconfiguration((ctx, builder) => { builder .setbasepath(appcontext.basedirectory) .addjsonfile("appsettings.json", true, true) .addjsonfile($"appsettings.{ctx.hostingenvironment.environmentname}.json", true, true) .addenvironmentvariables() ; }) .configureservices((ctx, services) => { services.addlogging(); services.addhostedservice<customhostservice>(); }) .useconsolelifetime() ;
public class customhostservice: ihostedservice{ private ilogger _logger; private task _executingtask; public task startasync(...) { _logger.loginformation($"{nameof(customhostservice):}start"); _executingtask = executeasync(...); if(_executingtask.iscompleted){ return _executingtask; } return task.completedtask; } public task stopasync(cancellationtoken cancellationtoken) { return task.whenany(_executingtask, task.delay(timeout.infinite, cancellationtoken)); } public task executeasync(...) { _logger.loginformation($"{nameof(customhostservice):executing}") return task.delay(5000); } }
如上,我们自定义的 customhostservice
需要实现 ihostedservice
接口,当然,我们可以直接继承 backgoundservice
类。
在实现了 ihostedservice
接口后,我们通过 services.addhostedservice<>()
进行注入,或者通过 service.addtransient<ihostedservice,thostedservice>()
进入注入。
启动以上项目,我们发现,我们的程序默认的hosting environment
一直是production
,那么如何修改呢 ??
配置环境变量
在aspnetcore项目中,我们可以通过设置环境变量aspnetcore_environment
的值来指定主机环境变量的。而在generic host 中暂时没有这一项配置。
如果查看ihostbuilder
的扩展,我们会发现以下方法:
new hostbuilder() .usecontentroot(...) .useenvironment(...) ...
查看源代码后,我们可以通过configurehostconfiguration()
方法将这些配置配置到主机中。
现在我们假设我们以dotnetcore_environment
来指定generichost的环境。
new hostbuilder().configurehostconfiguration(builder => { builder.addinmemorycollection(new dictionary<string, string> { [hostdefaults.environmentkey] = environment.getenvironmentvariable("dotnetcore_environment"), }) // nuget:microsoft.extensions.configuration.commandline //.addcommandline(args) ; }) //...
现在让我们打开命令行测试下。设置完成环境变量后我们通过dotnet run
启动程序。查看输出,host environment 变成为 stage
# 设置环境变量$env:dotnetcore_environment='stage'# 查看环境变量$env:dotnetcore_environment
当然我们也可以通过 commandline 的参数来设置启动的环境变量等值。
install-package microsoft.extensions.configuration.commandline
在configurehostconfiguration()
中使用.addcommandline(args)
来指定参数。
现在我们可以通过 dotnet run --environment=development
来指定dev环境了,此时我们发现我们终于成功加载appsettings.development.json
中的配置信息了。
使用autofac来替代默认的 di
简单认识一下autofac
一个第三方的依赖注入容器,相对microsft.extensions.dependencyinjection
使用更加简单方便。
集成到host中
通过nuget安装以下两个包
install-package autofac install-package autofac.extensions.dependencyinection
我们可以使用useserviceproviderfactory()
和service.addautofac()
将默认的di 替换成 autofac
;
使用configurecontainer<containerbuilder>()
可以使用autofac来注入服务;
//省略了非关键代码static ihostbuilder createdefaulthost(string[] args) => new hostbuilder()//...略 .configureservices((ctx, services) => { services.addlogging(x=>{x.addconsole();}); services.addautofac(); }) .configurecontainer<containerbuilder>(builder => { builder.registertype<customhostservice>() .as<ihostedservice>() .instanceperdependency(); }) .useserviceproviderfactory<containerbuilder>(new autofacserviceproviderfactory())//...略
总结
个人认为出现generichost解决的几个痛点,相对aspnetcore中的管道机制,控制台程序如果不依靠generichost来管理di,想进行大量microsoft.extensions
包的集成会非常困难。通过ihostedservice,可以方便的进行服务的托管。
以上就是使用generic-host的方法的详细内容,更多关于使用generic-host的资料请关注其它相关文章!