欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

快速了解如何在.NETCORE中使用Generic-Host建立主机

程序员文章站 2022-03-07 12:45:42
.netcore 中的 generic host本文以自己在工作中学习和使用.net core generic-host 作一个总结。前言在创建的aspnetcore项目中,我们可以在main()中看...

.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的资料请关注其它相关文章!