简体   繁体   English

如何使用通用主机 (HostBuilder) 为 .NET Core 控制台应用程序设置托管环境名称

[英]How to set hosting environment name for .NET Core console app using Generic Host (HostBuilder)

I am setting up a .NET Core 2.x console app as a Windows service and need to load an appsettings json file based on the environment.我正在将 .NET Core 2.x 控制台应用程序设置为 Windows 服务,需要根据环境加载 appsettings json 文件。 I was thinking to start the service with a command line argument that identifies the environment.我正在考虑使用标识环境的命令行参数启动服务。 How can I do that in Visual Studio?我怎样才能在 Visual Studio 中做到这一点? No matter what I set in the project settings, the EnvironmentName value is always "Production".无论我在项目设置中设置什么,EnvironmentName 值始终为“Production”。

How can I set my environment from a command line argument?如何从命令行参数设置我的环境?

var hostBuilder = new HostBuilder()
                 .UseContentRoot(Directory.GetCurrentDirectory())
                 .ConfigureAppConfiguration((hostingContext, config) =>
                 {
                     var env = hostingContext.HostingEnvironment;
                     config.AddCommandLine(args);
                     config.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: false, reloadOnChange: true);
                     config.AddEnvironmentVariables();
                 })
                 .ConfigureServices((hostContext, services) =>
                 {
                     //Inject additional services as needed
                     services.AddHostedService<JobRunner>();
                });

在此处输入图像描述

You can set the environment from the command line variables via the ConfigureHostConfiguration extension method.您可以通过ConfigureHostConfiguration扩展方法从命令行变量设置环境。

Set up the configuration for the builder itself.为构建器本身设置配置。 This will be used to initialize the Microsoft.Extensions.Hosting.IHostEnvironment for use later in the build process.这将用于初始化 Microsoft.Extensions.Hosting.IHostEnvironment 以供稍后在构建过程中使用。

var hostBuilder = new HostBuilder()
    .UseContentRoot(Directory.GetCurrentDirectory())
    .ConfigureHostConfiguration(configurationBuilder => {
        configurationBuilder.AddCommandLine(args);
    })
    .ConfigureAppConfiguration((hostingContext, cfg) =>
    {
        // ...

        var env = hostingContext.HostingEnvironment;
        Console.WriteLine(env.EnvironmentName); // Test
        // ...
    });
    
    // ...

    hostBuilder.Build();

In Visual Studio, you configure the application arguments with the same ones as being used by dotnet run which is --environment ,在 Visual Studio 中,您将应用程序 arguments 配置为与dotnet run使用的相同,即--environment
eg dotnet run --environment Test .例如dotnet run --environment Test

Without this application argument, the hosting environment defaults back to Production .如果没有此应用程序参数,托管环境将默认返回到Production

在此处输入图像描述

To pick up the hosting environment from environment variables, you can also add:要从环境变量中获取托管环境,您还可以添加:

.ConfigureHostConfiguration(config =>
{
    config.AddEnvironmentVariables();
})

Then use Environment environment variable to pass the actual environment.然后使用Environment环境变量来传递实际环境。

In Visual Studio , you can add an environment variable under the Debug tab of the console application properties.Visual Studio中,您可以在控制台应用程序属性的“调试”选项卡下添加环境变量。 For a console application the environment variable provider name must be prefixed by DOTNET_ for the generic host builder to recognize it.对于控制台应用程序,环境变量提供程序名称必须以DOTNET_为前缀,以便通用主机构建器识别它。 In this case, the provider name is DOTNET_ENVIRONMENT .在这种情况下,提供者名称是DOTNET_ENVIRONMENT

Visual Studio 2019 图像

If this provider name is not specified, the default is Production .如果未指定此提供程序名称,则默认为Production

Reference: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/generic-host?view=aspnetcore-5.0#host-configuration参考: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/generic-host?view=aspnetcore-5.0#host-configuration

Another method is to use the "UseEnvironnement" method directly on the host builder:另一种方法是直接在主机生成器上使用“UseEnvironnement”方法:

https://docs.microsoft.com/en-us/dotnet/api/microsoft.extensions.hosting.hostinghostbuilderextensions.useenvironment?view=dotnet-plat-ext-5.0 https://docs.microsoft.com/en-us/dotnet/api/microsoft.extensions.hosting.hostinghostbuilderextensions.useenvironment?view=dotnet-plat-ext-5.0

For example:例如:

   public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .UseEnvironment("dev") // Magic is here
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseUrls("http://0.0.0.0:8081");
                    webBuilder.UseStartup<Startup>();
                });

In Visual Studio 2022 and .NET 6.0, appsettings.json and appsettings.[EnvironmentName].json are automatically included in configuration sources when using HostBuilder:在 Visual Studio 2022 和 .NET 6.0 中,appsettings.json 和 appsettings.[EnvironmentName].json 在使用 HostBuilder 时自动包含在配置源中:

程序.cs

So there is no need to manually add these in ConfigureServices.因此无需在 ConfigureServices 中手动添加这些。

You still need to set EnvironmentName in launchSettings.json or as a commandline argument as shown in the other answers.您仍然需要在 launchSettings.json 中设置 EnvironmentName 或作为命令行参数,如其他答案所示。

If you are using visual studio and you have project configuration (Debug, Release, CustomUser...) then you could include appsettings.[config-name].json like this:如果您使用的是 Visual Studio,并且您有项目配置(Debug、Release、CustomUser...),那么您可以像这样包含 appsettings.[config-name].json:

Host
  .CreateDefaultBuilder(args)
  .ConfigureAppConfiguration((context, builder) => {
     //add visual studio configuration manager
     builder.AddJsonFile($"appSettings.{Assembly.GetExecutingAssembly().GetCustomAttribute<AssemblyConfigurationAttribute>().Configuration}.json", true);
     ...
   })
    ...

If you are using Visual Studio 2022 with.Net 5, the UI could be a bit overwhelming.如果您将 Visual Studio 2022 与 .Net 5 一起使用,则 UI 可能会有点压倒性。 Its simple to edit launchSettings.json file under properties.在属性下编辑launchSettings.json文件很简单。

属性下的 LaunchSettings

Mine looks as follows.我的看起来如下。 Note its DOTNET_ENVIRONMENT and NOT ASPNETCORE_ENVIRONMENT for .NET Core console app using Generic Host (HostBuilder)注意它的DOTNET_ENVIRONMENT不是ASPNETCORE_ENVIRONMENT用于使用通用主机 (HostBuilder) 的 .NET 核心控制台应用程序

{
  "profiles": {
    "Bvh.HrSita.DbMigrator": {
      "commandName": "Project",
      "environmentVariables": {
        "DOTNET_ENVIRONMENT": "Development"
      }
    },
    "Bvh.HrSita.DbMigrator.Prod": {
      "commandName": "Project",
      "environmentVariables": {
        "DOTNET_ENVIRONMENT": "Production"
      }
    },
    "Bvh.HrSita.DbMigrator.Stag": {
      "commandName": "Project",
      "environmentVariables": {
        "DOTNET_ENVIRONMENT": "Staging"
      }
    },
    "Docker": {
      "commandName": "Docker"
    }
  }
}

Now select what ever profile you want when you launch the project.现在 select 当你启动项目时你想要什么配置文件。 The following shows it all along with Program.cs.下面将与 Program.cs 一起显示它。

在 Visual Studio 2022 中选择启动配置文件

And finally if you are trying to run the same in an Azure DevOps pipeline, the task should be as shown below.最后,如果您尝试在 Azure DevOps 管道中运行相同的任务,则任务应如下所示。 The arguments should have --environment Production. arguments 应该有 --environment Production。 Note that adding env: is somehow NOT working for me as suggested here .请注意,按照此处的建议,添加 env: 对我不起作用

    - task: DotNetCoreCLI@2
      displayName: 'Run DbMigrator Project on the newly provisoned database'
      inputs:
        command: run
        projects: '$(Pipeline.Workspace)/$(finalBuildArtifactName)/src/Bvh.HrSita.DbMigrator/Bvh.HrSita.DbMigrator.csproj'
        arguments: '--configuration $(BuildConfiguration) --environment Production'
      env: 
        DOTNET_ENVIRONMENT: Production

To add to pfx's accepted answer above, in Visual studio 2022 , the environment variable can be set either via Properties window in UI:要添加到 pfx 上面接受的答案,在Visual Studio 2022中,可以通过 UI 中的 Properties window 设置环境变量:

在此处输入图像描述

or set the environment variable:或设置环境变量:

在此处输入图像描述

or directly edit the launchSettings.json file under Properties and add command line arguement:或者直接编辑属性下的launchSettings.json文件,添加命令行参数:

在此处输入图像描述

I run into this issue time and time again and can never remember what my solution was from the previous time I ran into it.我一次又一次地遇到这个问题,并且永远不记得上次遇到它时我的解决方案是什么。 Typically, I'm simply trying to get a Development and Production environment in my console app like you get by default with a web app (configured with launchSettings.json and other more buried mechanisms).通常,我只是想在我的控制台应用程序中获得一个DevelopmentProduction环境,就像您默认使用 web 应用程序(配置有 launchSettings.json 和其他更隐蔽的机制)一样。

At the beginning of my Program.cs in my console app, I add:在我的控制台应用程序中Program.cs的开头,我添加:

#if DEBUG
    Environment.SetEnvironmentVariable("ASPNETCORE_ENVIRONMENT", "Development");
#endif

var env = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
Console.WriteLine($"{env}");

If the debug condition is not met, it always defaults to Production as the OP mentioned.如果不满足调试条件,它总是默认为 OP 提到的Production

However, you could also just as easily set more simple variables with the debug condition:但是,您也可以使用调试条件轻松设置更简单的变量:

var env = "Production";
#if DEBUG
    env = "Development";
#endif
Console.WriteLine($"{env}");

It's not command line, but should work as a solution.它不是命令行,但应该作为一种解决方案。 I also rarely see this suggested and found this digging through one of my older projects (after hours of searching online), so I'm not sure if it has any downsides (other than mostly only being good for one other environment besides Production)?我也很少看到这个建议,并且发现这个是通过我的一个旧项目进行挖掘的(在网上搜索了几个小时之后),所以我不确定它是否有任何缺点(除了主要只对生产之外的其他环境有益)? Please leave a comment if there are other gotchas.如果还有其他陷阱,请发表评论。

Part of the reason for posting this answer is so my future self can hopefully find it more quickly than this time around.发布此答案的部分原因是希望我未来的自己能比这次更快地找到它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何使用HostBuilder通用主机ref StopAsync OperationCanceledException设置ShutdownTimeout - How to set ShutdownTimeout using HostBuilder Generic Host ref StopAsync OperationCanceledException 如何使用通用主机生成器运行 .NET Core 控制台应用程序 - How to run .NET Core Console app using generic host builder ASP.NET Core通用主机(HostBuilder)尝试激活时无法解析类型…的服务 - ASP.NET Core Generic Host (HostBuilder) Unable to resolve service for type … while attempting to activate 如何使用 Z303CB0EF9EDB9082AZ61BBBE582 将 REST API 添加到用 .NET Framework 4.8 编写的控制台应用程序中? - How to add REST API to console app written in .NET Framework 4.8 using .NET generic host? 如何在 .NET Core 5 控制台应用程序中托管 REST web api - How to host a REST web api in a .NET core 5 console app 如何以编程方式停止/退出/终止 dotnet core HostBuilder 控制台应用程序? - How to stop/exit/terminate dotnet core HostBuilder console application programmatically? .NET Core:如何在控制台应用程序中为 .NET 通用主机配置 JSON 库? - .NET Core: How to configure JSON library for .NET Generic Host in console application? .net core 3.0,服务未使用 HostBuilder 注册以进行集成测试 - .net core 3.0, Service not register using HostBuilder for Integration Tests ASP.NET Core在构建过程中设置托管环境 - ASP.NET Core set hosting environment in build process 在 .NET Core 通用主机中配置应用程序配置时访问记录器 - Accessing logger when configuring app configurations in .NET Core generic host
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM