快速了解如何在.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


猜你喜欢
- 我们首先看一下效果图,有个整体的印象好了,为了便于理解,这里就按照动画所见内容依次展开来说准备这里决定采用canvas(画布)和paint(
- package TOOLS;import java.io.BufferedReader;import java.io.File;import
- 前言:自定义View可以分为两种方式:第一种通过继承ViewGroup,内部通过addView的方式将其他的View组合到一起。第二种则是通
- 1、ThreadLocal 使用原理前文我们讲过ThreadLocal的主要用途是实现线程间变量的隔离,表面上他们使用的是同一个Thread
- /** * 进行BigDecimal对象的加减乘除,四舍五入等运算的工具类 * * @author Marydon * @createTi
- 一.正则基础1. []方括号表示匹配可以匹配方括号中的任意点单个字符,方括号只允许匹配单个字符。2. | 或表示两项之间的一个选择,它不能和
- spring boot RestTemplate 发送get请求踩坑闲话少说,代码说话RestTemplate 实例手动实例化,这个我基本不
- 前言C#基于NAudio工具对Wav音频文件进行剪切,将一个音频文件剪切成多个音频文件注:调用方法前需要导入NAudio.dll或者在NuG
- 最近有个项目的几张表,数量级在千万以上,技术栈是SpringBoot+Mybatis-plus+MySQL。如果使用单表,在进行查询操作,非
- 我们知道android是基于Looper消息循环的系统,我们通过Handler向Looper包含的MessageQueue投递Message
- 引言 在多线程中,为了使线程安全,我们经常会使用synchronized和Lock进行代码同步和加锁,但是具体两者有什么区别,什
- 数据层测试事务回滚pom.xml导入对应的一些坐标,mysql,Mp,等<dependency> &
- Flutter自适应瀑布流前言:在电商app经常会看到首页商品推荐的瀑布流,或者类似短视频app首页也是瀑布流,这些都是需要自适应的,才能给
- 前言相信大家在写前端脚本的时候经常会遇到发送数据到后台的情况,但是由于浏览器的限制,不同域名之间的数据是不能互相访问的,那前端怎么和后端如何
- 本文实例讲述了C#实现去除Strings中空格的方法,分享给大家供大家参考。具体实现方法如下:一般来说,你或许知道你能使用String.Tr
- 一般来说,常用的设计模式有以下八种:单例、工厂、观察者、代理、命令、适配器、合成、访问者单例模式:目的是为了让系统中只有一个调用对象,缺点是
- 本文实例讲述了Android编程实现自定义进度条颜色的方法。分享给大家供大家参考,具体如下:android 自定义进度条颜色先看图基于产品经
- springboot项目启动的时候参数无效今天启动一个springboot项目发现启动的时候输入的参数都是不能生效,但是yaml文件的配置却
- SDK是Software Development Kit的缩写,中文意思是“软件开发工具包”。这是一个覆盖面相当广泛的名词,可以这么说:辅助
- 最近接触了Android自定义控件,涉及到自定义xml中得属性(attribute),其实也很简单,但是写着写着,发现代码不完美了,就是在a