【问题标题】:How do I get the current environment (QA/Prod/DEV) name in net core C#?如何在 net core C# 中获取当前环境 (QA/Prod/DEV) 名称?
【发布时间】:2019-11-06 21:34:13
【问题描述】:

我想在我的代码中获取当前环境的名称(QA/Prod/DEV),这样我就可以在调用 AddJsonFile 时使用该名称

*请注意,此代码不是用于应用程序,而是用于使用带有 NUNIT 的测试资源管理器测试运行器的 selenium 单元测试,因此我没有可以使用的 Startup.cs 类或 ihostingenvironment。

我想这样做,我需要在 launchsettings.json 中检索“Hosting:Environment”或“ASPNETCORE_ENVIRONMENT”值,我认为它应该代表当前的 Visual Studio 进程/会话/环境。请参阅下面的Environment.GetEnvironmentVariable("Hosting:Environment"),了解我如何检索此 launchsettings.json 值。

    public static IConfiguration InitConfiguration()
    {
        LaunchSettingsFixture LaunchSettings = new LaunchSettingsFixture();

        var environmentName = Environment.GetEnvironmentVariable("Hosting:Environment");

        var builder = new ConfigurationBuilder()
            .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
            .AddJsonFile($"appsettings.{environmentName}.json", true)
            .AddEnvironmentVariables();
        var configuration = builder.Build();

        // Testing to see if the above worked
        string url = configuration["url"];
        string driverdirectory = configuration["driverdirectory"];

        return configuration;
    }

在上面的代码中,我希望Environment.GetEnvironmentVariable("Hosting:Environment") 会返回一个值为“blah”的字符串,因为我在当前进程/配置文件/环境下拉菜单中选择了“blah”(运行旁边的下拉菜单)按钮)。请参阅下面的照片了解我当前的流程/配置文件选择,并在下面的 launchsettings.json 文件中查看我的 json 文本...

    {
    "profiles": {
          "Wikipedia.UITest": {
            "commandName": "Project"
               },
          "UAT": {
            "commandName": "Executable",
            "environmentVariables": {
               "Hosting:Environment": "UAT"
               }
           },
          "blah": {
            "commandName": "Executable",
            "environmentVariables": {
              "Hosting:Environment": "Development",
              "containerName": "Testing"
            }
          },
          "Prod": {
            "commandName": "Executable",
            "environmentVariables": {
              "Hosting:Environment": "prod"
            }
          }
        }
      }

取而代之的是Environment.GetEnvironmentVariable("Hosting:Environment") 将launchsettings.json 文件中的最后一个实例返回给我(无论我在下拉菜单中选择什么,如屏幕截图所示)。即它返回“prod”的值。再次,我想提一下这是一个 NUNIT NET CORE 项目,我正在使用测试资源管理器来运行和调试测试(见下面的截图)

另外,我不知道下面的代码是否相关,但下面是我如何设置环境变量...

    public class LaunchSettingsFixture
    {
        public LaunchSettingsFixture()
        {
            using (var file = File.OpenText("Properties\\launchSettings.json"))
            {
                var reader = new JsonTextReader(file);
                var jObject = JObject.Load(reader);

                var variables = jObject
                    .GetValue("profiles")
                    //select a proper profile here
                    .SelectMany(profiles => profiles.Children())
                    .SelectMany(profile => profile.Children<JProperty>())
                    .Where(prop => prop.Name == "environmentVariables")
                    .SelectMany(prop => prop.Value.Children<JProperty>())
                    .ToList();

                foreach (var variable in variables)
                {
                    Environment.SetEnvironmentVariable(variable.Name, variable.Value.ToString());
                }
            }
        }

    }  

【问题讨论】:

  • 在调用 LaunchSettingsFixture 之前 Hosting:Environment 的值是多少?该代码似乎不正确,因为它读取文件并按照它们出现的顺序进行设置,因此您从文件的最后一个条目中获取值也就不足为奇了。
  • 调用LaunchSettingsFixture之前的值为null。根据这个答案:stackoverflow.com/a/43951218launchSettings.json 不被测试运行者考虑。所以我必须首先使用 SetEnvironmentVariable 设置环境变量。该答案中提供的代码是我用来设置变量的代码(您可以在上面看到)。它有 39 票,所以我不认为这是错误的?
  • 我鼓励您在可以看到的地方打印出这些值。即使在控制台应用程序中,也可以看出这个 sn-p 只是转储所有配置文件的所有变量。我认为“在此处选择正确的配置文件”的评论旨在让您编写更多代码来选择正确的配置文件,而不是告诉您代码在做什么。
  • 我认为情况并非如此,因为如果我要“选择适当的配置文件”,那将违背 Visual Studio 将“当前”配置文件/服务中的变量返回给我的目的/环境,不是吗?我认为当您在下拉列表中选择配置文件(在“运行”按钮旁边),然后运行程序或测试时,Visual Studio 应该从该配置文件运行,因此 Visual Studio 为我选择配置文件,返回“当前”配置文件上的启动设置中的值(即基于在下拉列表中选择的配置文件)
  • 我认为它不受支持。请参阅此issue。在解决将 launchsettings.json 环境变量传递给测试运行程序之前,您可能必须构建不依赖此 UI 设置的东西。

标签: c# visual-studio .net-core


【解决方案1】:

正如@Mike Zboray 正确写的那样,VS 和 Rider 都没有将当前的启动配置文件传递给测试运行器,因此目前无法通过 launchSettings.json 设置环境变量。

关于LaunchSettingsFixture,它确实会检查所有设置并从每个配置文件中添加每个环境变量,这就是为什么您总是会看到最新的生产配置。可能在您引用作者的答案中暗示在项目中使用单一启动配置文件。

一种可能的方法是使用构建配置设置并有条件地将 appsettings.*.json 复制到输出文件夹。类似于在 .NET Core 之前使用完整的 .NET Framework。

在项目文件中,您可以根据构建配置文件配置要复制的文件:

<ItemGroup>
  <None Update="appsettings.$(Configuration).json">
    <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
  </None>
  <None Update="appsettings.json">
    <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
  </None>
</ItemGroup>

复制所需的配置文件后,您可以将它们添加到配置生成器中:

public static IConfiguration InitConfiguration()
{
    var settingsFiles = Directory.GetFiles(Directory.GetCurrentDirectory(), "appsettings.*.json"));
    if (settingsFiles.Length != 1) throw new Exception($"Expect to have exactly one configuration-specfic settings file, but found {string.Join(", ", settingsFiles)}.");
    var settingsFile = settingsFiles.First();

    var builder = new ConfigurationBuilder()
        .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
        .AddJsonFile(settingsFile)
        .AddEnvironmentVariables();
    var configuration = builder.Build();

    // Testing to see if the above worked
    string url = configuration["url"];
    string driverdirectory = configuration["driverdirectory"];

    return configuration;
}

请记住,现在您必须更改 构建配置 而不是启动配置文件才能针对所选环境运行测试。

【讨论】:

  • 这行得通。谢谢!希望 Microsoft 在 Profiles 中添加执行此操作的功能
猜你喜欢
  • 1970-01-01
  • 2020-11-25
  • 2016-05-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-10
相关资源
最近更新 更多