.Net Core 5 控制台应用程序,在 Program.Main 中完成时未为环境加载应用程序设置

.Net Core 5 Console App, appsettings not loading for environment when done in Program.Main

我希望我的 .Net Core 5 控制台应用程序根据 DOTNET_ENVIRONMENT 环境变量从适当的 appsettings 文件中 select 进行设置。我在 Visual Studio 2019 调试器中通过 运行 对其进行测试,并从我的 launchSettings.json 文件中获取环境。

在 .Net Core 5 控制台应用程序中,我有 4 个“appsettings”文件:

每个文件属性设置为生成操作:内容,并复制到输出目录:如果较新则复制。

在我的 launchSettings.json 中,我将我的环境设置为“暂存”,如下所示:

 {
  "profiles": {
    "MyAppName": {
      "commandName": "Project",
      "dotnetRunMessages": "true",
      "environmentVariables": {
        "DOTNET_ENVIRONMENT": "Staging"
      }
    }
  }
}

我需要在 Program.cs 的“Main”方法中访问我的配置,因此 class 我在静态构造函数中设置模块级字符串变量“_environment” :

_environment = Environment.GetEnvironmentVariable("DOTNET_ENVIRONMENT");

这行得通;值“Staging”被加载到变量 _environment 中。

然后我将我的配置加载到静态变量中,如下所示:(编辑——这是我的错误,假设这个静态 属性 在静态 ctor 之后加载。实际上它在静态 ctor 之前加载。这意味着未设置 _environment 变量,这意味着我的特定于环境的 appsettings 文件从未加载过)。

private static IConfiguration Configuration { get; } = new ConfigurationBuilder()
    .SetBasePath(Directory.GetCurrentDirectory())
    .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
    .AddJsonFile($"appsettings.{_environment}.json", optional: true, reloadOnChange: true)
    .AddEnvironmentVariables()
    .Build();

当我检查配置的内容时,我发现它只从 appsettings.json 加载值。它没有从 appsettings.Staging.json 加载值。 我正在寻找的具体值是“ConnectionStrings”。这是 ConnectionStrings 部分在 appsettings.json:

中的样子
"ConnectionStrings": {
    "ConnectionStringName": "Data Source=SqlDevelopment; Initial Catalog=MyTable; Integrated Security=SSPI;",
  }

这就是同一部分在 appsettings.Staging.json 中的样子:

"ConnectionStrings": {
    "ConnectionStringName": "Data Source=SqlStaging; Initial Catalog=MyTable; Integrated Security=SSPI;",
  }

但是当我从配置中读取数据源时,它始终是“SqlDevelopment”,即使环境是暂存的。

尝试失败后,我尝试加载这4个Nuget包,但没有效果:

  1. Microsoft.Extensions.Configuration
  2. Microsoft.Extensions.Configuration.活页夹
  3. Microsoft.Extensions.Configuration.环境变量
  4. Microsoft.Extensions.Configuration.Json

我错过了什么?

控制台应用程序检查 DOTNET_ 环境变量,而不是 ASPNETCORE_ 变量。这不是一个新的变化。它至少可以追溯到 .NET Core 3.1。您需要改为设置 DOTNET_ENVIRONMENT

ASP.NET 除了 DOTNET_ 变量外,核心应用程序还使用任何以 ASPNETCORE_ 为前缀的环境变量。

来自docs :

The default configuration loads environment variables and command line arguments prefixed with DOTNET_ and ASPNETCORE_. The DOTNET_ and ASPNETCORE_ prefixes are used by ASP.NET Core for host and app configuration, but not for user configuration. For more information on host and app configuration, see .NET Generic Host.

PS:就在 10 分钟前,我遇到了同样的问题并意识到我设置了 DOTNETCORE_ENVIRONMENT 而不是 DOTNET_ENVIRONMENT

I need access to my configuration in the "Main" method in Program.cs, so in that class I am setting a module-level string variable "_environment" like so in the static constructor:

_environment = Environment.GetEnvironmentVariable("DOTNET_ENVIRONMENT");

事情不是这样的。您需要使用 IHostEnvironment.EnvironmentName。如果您需要在 Main() 方法中访问您的配置,那么您做错了什么,读取环境变量是读取 (ASP).NET Core 环境名称的错误方法。

“(ASP).NET Core 环境名称”可以通过多种方式设置,一种 方式是OS 环境变量。但它们不是必须的,它们也可以通过命令行参数提供。

IHostEnvironment.EnvironmentName 是获取环境名称的正确方法。

谢谢大家,尤其是@CodeCaster 对我的帮助。

问题是设置静态配置时 _environment 变量为空字符串。我假设因为我在静态构造函数中设置它是可用的,但静态 ctor 实际上是 运行 after 我设置了我的静态配置,所以 _environment 是一个空字符串,因此从未加载“暂存”配置。

我修改了代码,这样运行时就不可能以我没有预料到的顺序设置变量:

    private static IConfiguration Configuration { get; } = new ConfigurationBuilder()
        .SetBasePath(Directory.GetCurrentDirectory())
        .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
        .AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("DOTNET_ENVIRONMENT")}.json", optional: true, reloadOnChange: true)
        .Build();

许多张贴者基本上告诉我“你做错了”。我意识到运行时在调用 Host.CreateDefaultBuilder() 之后提供了一个依赖注入的配置。由于超出此问题范围的原因,我碰巧需要在 Program.Main 内的调用发生之前进行配置。如果我不需要在 Program.Main 中配置,那么在调用 Host.CreateDefaultBuilder 之前,none 将是必要的。