.NETCORE 中的 Generic Host

本文以自己在工作中学习和使用.net core generic-host 作一个总结。

前言

在创建的ASPNETCORE项目中,我们可以在Main()中看见,我们通过IWebHostBuild创建了一个IWebHost,而微软提供了WebHost.CreateDefaultBuilder(args)来帮助我们更轻松得创建WebHost

常常我们的需求不需要创建Web项目,比如后台任务,那么我们如何像使用AspNetCore一样创建控制台项目。

如何在控制台程序中创建主机

  1. 通过dotnet new console 创建一个控制台项目
  2. 通过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://github.com/missxueo/docs-generic-host

Generic-Host 快速使用指南的更多相关文章

  1. Rancher 快速上手指南操作(1)

    Rancher 快速上手指南操作(1)该指南知道用户如何快速的部署Rancher Server 管理容器.前提是假设你的机器已经安装好docker了.1 确认 docker 的版本,下面是 ubunt ...

  2. [转]Rancher 快速上手指南操作(1)

    本文转自:http://www.cppblog.com/zhiyewang/archive/2016/03/17/213053.aspx Rancher 快速上手指南操作(1)该指南知道用户如何快速的 ...

  3. AngularJS快速入门指南20:快速参考

    thead>tr>th, table.reference>tbody>tr>th, table.reference>tfoot>tr>th, table ...

  4. AngularJS快速入门指南19:示例代码

    本文给出的大部分示例都可以直接运行,通过点击运行按钮来查看结果,同时支持在线编辑代码. <div ng-app=""> <p>Name: <input ...

  5. AngularJS快速入门指南18:Application

    是时候创建一个真正的AngularJS单页面应用程序了(SPA). 一个AngularJS应用程序示例 你已经了解了足够多的内容来创建第一个AngularJS应用程序: My Note Save Cl ...

  6. AngularJS快速入门指南17:Includes

    使用AngularJS,你可以在HTML中包含其它的HTML文件. 在HTML中包含其它HTML文件? 当前的HTML文档还不支持该功能.不过W3C建议在后续的HTML版本中增加HTML import ...

  7. AngularJS快速入门指南16:Bootstrap

    thead>tr>th, table.reference>tbody>tr>th, table.reference>tfoot>tr>th, table ...

  8. AngularJS快速入门指南15:API

    thead>tr>th, table.reference>tbody>tr>th, table.reference>tfoot>tr>th, table ...

  9. AngularJS快速入门指南14:数据验证

    thead>tr>th, table.reference>tbody>tr>th, table.reference>tfoot>tr>th, table ...

  10. AngularJS快速入门指南13:表单

    一个AngularJS表单是一组输入型控件的集合. HTML控件 HTML输入型标签标包括: input标签 select标签 button标签 textarea标签 HTML表单 HTML表单将各种 ...

随机推荐

  1. web api 请求结果中页面显示的json字符串与json对象结果不一致

    我在前端调用这个api的时候也是百思不得其解,明明看到页面上的结果ID是不一样的,但是在js中使用的时候,却一直有重复ID的情况 后来才发现原来是long这个类型的原因,JavaScript中Numb ...

  2. 精妙SQL语句大全

    一.基础 1.说明:创建数据库 CREATE DATABASE database-name 2.说明:删除数据库 drop database dbname 3.说明:备份sql server --- ...

  3. Asp.NetCore安全验证之JWT

    本文只是介绍了下基于AspNetCore自带的System.IdentityModel.Tokens.Jwt.dll工具在项目中Token的应用. 我这里谈到的很浅显就两点: 一,超时时间 二,数据的 ...

  4. 记开发个人图书收藏清单小程序开发(六)Web开发

    Web页面开发暂时是没有问题了,现在开始接上Ptager.BL的DB部分. 首先需要初始化用户和书房信息.因为还没有给其他多余的设计,所以暂时只有个人昵称和书房名称. 添加 Init Razor Pa ...

  5. ANE-调用原生组件横屏定位问题

    当我们的应用是横的时候,利用ANE调用原生组件如果处理不当,掉出来的组件会是竖的.那么我么要怎么做才能免去自己手动旋转组件这个破事呢.其实很简单 webView = [[UIWebView alloc ...

  6. 关于onetoone 的2张表关联中间表的策略

    ProductCategoryVO.java 中间关联表 package com.syscxp.header.billing; import com.syscxp.header.search.SqlT ...

  7. 北航操作系统实验2019:Lab4-1代码实现参考

    北航操作系统实验2019:Lab4-1代码实现参考 部分实现参考自Github前辈们的项目,经过一定程度的勘误. 如果这份代码中存在任何问题或错误,请务必不吝在评论区指出. Exercise 4.1 ...

  8. flask 安装

    flask官网 : http://docs.jinkan.org/docs/flask/installation.html (基本上就是按照官网思路一点一点来的) 1,安装easy_install: ...

  9. GPS坐标转百度地图坐标

    百度地图提供了相关API:BMap.Convertor.translate, 但是使用上存在部分限制:1.次数限制:2.异步回调 可以用如下方法: /** * 地图位置计算工具(将GPS坐标转换成百度 ...

  10. STM32-RTC实时时钟-毫秒计时实现

    OS:Windows 64 Development kit:MDK5.14 IDE:UV4 MCU:STM32F103C8T6 1.RTC时钟简介 STM32 的实时时钟(RTC)是一个独立的定时器, ...