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

作者:蝴蝶刀刀 时间:2022-05-08 15:04:12 

.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,可以方便的进行服务的托管。

来源:https://www.imooc.com/article/281833

标签:.net,Generic-Host,建立主机
0
投稿

猜你喜欢

  • 改进c# 代码的五个技巧(一)

    2021-07-17 23:49:30
  • windows如何使用bat脚本后台启动/停止和重启jar包服务

    2022-02-27 12:28:36
  • SpringBoot MongoDB 索引冲突分析及解决方法

    2023-01-23 06:28:05
  • 浅谈Java日志框架slf4j作用及其实现原理

    2022-11-02 19:02:04
  • java 中newInstance()方法和new关键字的区别

    2023-11-25 07:17:26
  • Java8 HashMap键与Comparable接口小结

    2023-11-29 10:10:31
  • Kafka 日志存储实现过程

    2021-11-01 05:04:00
  • spring boot 枚举使用的坑整理

    2022-09-17 09:03:15
  • 深入学习C#网络编程之HTTP应用编程(下)

    2023-03-16 12:06:37
  • Java实现简易生产者消费者模型过程解析

    2023-12-03 01:33:26
  • java中Cookie被禁用后Session追踪问题

    2023-10-17 13:44:32
  • Java 读写锁源码分析

    2021-08-31 01:48:54
  • Spring Boot 如何解决富文本上传图片跨域问题

    2021-09-20 06:08:58
  • Java实现AWT四大事件的详细过程

    2023-11-28 18:39:52
  • SpringCloud中Eureka的配置及使用讲解

    2022-04-19 19:16:28
  • Mybatis是这样防止sql注入的

    2022-05-30 02:05:16
  • c#实现选择排序的示例

    2021-10-15 00:32:27
  • java使用Jsoup组件生成word文档

    2022-10-28 12:44:16
  • Spring boot的上传图片功能实例详解

    2022-10-09 09:52:00
  • 单点登录的三种方式和JWT的介绍与使用

    2023-05-19 22:10:59
  • asp之家 软件编程 m.aspxhome.com