Generic-Host 快速使用指南

Generic-Host 快速使用指南.NETCORE中的GenericHost本文以自己在工作中学习和使用.netcoregenerichost作一个总结。前言在创建的ASPNETCORE项目中,我们可以在中看见,

大家好,又见面了,我是你们的朋友全栈君。

.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

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/155472.html原文链接:https://javaforall.net

(0)
上一篇 2022年7月3日 下午9:16
下一篇 2022年7月3日 下午9:16


相关推荐

  • Django 模型_django反向生成model

    Django 模型_django反向生成model前言随着项目越来越大,采用写原生SQL的方式在代码中会出现大量的SQL语句,那么问题就出现了:1.SQL语句重复利用率不高,越复杂的SQL语句条件越多,代码越长。会出现很多相近的SQL语句。2.

    2022年7月29日
    9
  • 函数 Func

    函数 Func1 函数函数是用来完成特定任务的独立代码块 函数的参数 参数可以提供默认值 用来简化函数调用 参数可以当做传入参数也可以当做传出参数 即传入的参数值可以被修改 所有参数放在圆括号内函数的返回值 与 OC 的语法不通 以 func 关键字为前缀 有返回值用 来表示用返回值 并添加返回值类型函数类型 函数类型包括参数值类型和返回值类型 每一个函数类型可以当做是普通的类型来处理 可以做函数的

    2026年3月20日
    3
  • 深度学习在摄影技术中的应用与发展

    深度学习在摄影技术中的应用与发展本文来自作者 nbsp 言有三 nbsp 在 nbsp GitChat nbsp 上分享 深度学习在摄影技术中的应用与发展 阅读原文 查看交流实录 文末高能 编辑 哈比我是一个 AI 行业的从业者 也是一个摄影爱好者 之前我在 言有三工作室 公众号分享过一篇文章 干掉柯洁的下一步 阿尔法狗创始人又要毁掉这个行业 深度学习 感兴趣可以去看看 其中主要说的就是 DeepMind 的研究 已经让算法掌握了自动学习到构图 滤镜

    2026年3月17日
    2
  • html如何只刷新页面指定,js控制页面刷新 JS刷新当前页面的几种方法总结

    html如何只刷新页面指定,js控制页面刷新 JS刷新当前页面的几种方法总结JavaScriptlocation.reload()方法Location对象的reload()方法用于重新加载当前文档(页面),语法如下:location.reload(false|true)说明(实战帮有javascript课程与实训项目哦,可以一试)如果该方法参数为false或者省略参数。JS页面如何实现刷新指定DIV。。。其他DIV不刷新将innerHTML所…

    2022年7月12日
    18
  • C语言strstr函数实现

    C语言strstr函数实现自己实现C语言中的strstr函数,用的是朴素的模式匹配算法,还有可以优化的地方,下次想好了再写。/*strstr实现*/char*mystrstr(constchar*dest,constchar*src){ char*tdest=dest; char*tsrc=src; while(*tdest) { char*flag=tdest

    2022年6月25日
    31
  • 图书管理系统设计与实现—看这篇就够了

    图书管理系统设计与实现—看这篇就够了本课程设计的目的 1 掌握企业级应用系统的基本开发流程 2 培养开发者掌握应用系统设计的基本思路和方法 3 培养开发者分析 解决问题的能力 系统要实现的功能概述 1 用户登录 管理员或会员根据用户名和密码进行身份验证登录系统 2 图书管理 根据图书编号 图书名称查询图书基本信息添加 修改 删除图书 3 读者管理 根据账号 姓名查询读者基本信息 添加 修改 删除读者信息 4 图书分类管理 根据分类名称查询图书分类信息 添加 修改 删除图书分类

    2026年3月20日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号