在 .NET Core 中将应用设置与环境变量合并

Posted

技术标签:

【中文标题】在 .NET Core 中将应用设置与环境变量合并【英文标题】:Merging appsettings with environment variables in .NET Core 【发布时间】:2018-06-26 04:00:56 【问题描述】:

我在 Docker(在 Kubernetes 中)运行 .NET Core 应用,将环境变量传递给 Docker 容器并在我的应用中使用它们。

在我的 .NET Core 应用程序中,我有以下 C# 类:

public class EnvironmentConfiguration

    public string EXAMPLE_SETTING  get; set; 
    public string MY_SETTING_2  get; set; 

我这样设置我的appsettings

config.
    AddJsonFile("appsettings.json").
    AddJsonFile($"appsettings.docker.json", true).
    AddEnvironmentVariables();  

DI 设置:

services.Configure<EnvironmentConfiguration>(Configuration);

在我的控制器中,我这样使用它:

[ApiVersion("1.0")]
[Route("api/vversion:apiVersion/my")]
public class MyController : Controller

    private readonly IOptions<EnvironmentConfiguration> _environmentConfiguration;

    public MyController(IOptions<EnvironmentConfiguration> environmentConfiguration)
    
        _environmentConfiguration = environmentConfiguration;
    
       

我运行 docker:

docker run -p 4000:5000 --env-file=myvariables

文件myvariables 如下所示:

EXAMPLE_SETTING=example!!!
MY_SETTING_2=my-setting-2!!!!

这行得通。我可以使用我的_environmentConfiguration 并查看我的变量是否已设置。

但是...我想将环境变量与 appsettings 合并,以便在找不到环境变量时将 appsettings 中的值用作后备。以某种方式合并这两行:

services.Configure<EnvironmentConfiguration>(settings => Configuration.GetSection("EnvironmentConfiguration").Bind(settings));
services.Configure<EnvironmentConfiguration>(Configuration);

这有可能吗?

我的后备计划是继承 EnvironmentConfiguration 类并使用单独的 DI 注入两个单独的配置,然后在代码中“手动”合并它们,但这种解决方案是不可取的。

【问题讨论】:

我正在研究实现这样的目标,@Marcus,您能否将 dockerfile 添加到问题中以供我参考?如果您可以有 2 个版本,分别列出 env 文件和 env ,那就太好了。非常感谢 【参考方案1】:
config.
    AddJsonFile("appsettings.json").
    AddJsonFile("appsettings.docker.json", true).
    AddEnvironmentVariables();

实际上足以使用环境变量覆盖 appsettings 值。

假设您的 appsettings.json 文件中有以下内容;


  "Logging": 
      "Level": "Debug"
  

您可以通过将名为 Logging:Level 的环境变量设置为您的偏好值来覆盖 Logging.Level 的值。

请注意,: 用于在环境变量键中指定嵌套属性。

另请注意:来自docs;

如果您的系统上的环境变量名称中不能使用冒号 (:),请将冒号 (:) 替换为双下划线 (__)。

【讨论】:

双下划线确实解决了我在docker中的环境变量问题 双下划线确实是要走的路……在您想要传递嵌套配置值的 azure 容器实例中部署时也是如此。 这个链的顺序会影响哪个源优先吗?如果我们将上面的代码重新排列为config.AddEnvironmentVariables().AddJsonFile("appsettings.json").AddJsonFile($"appsettings.docker.json", true);,那么appsettings.docker.json 中的值是否会优先于其他两个源中的值,因为它是最后一次调用的? 我刚被下单抓到 - 把AddEnvironmentVariables() 作为最后一个电话,否则它不起作用!!! 您能否添加一个 appsettings 文件和 dockerfile 的示例以确保完整性?这将帮助人们(像我一样)轻松理解实际设置。如果您可以添加一个 docker 命令示例来展示如何通过设置变量来运行该图像,那就太好了。谢谢

以上是关于在 .NET Core 中将应用设置与环境变量合并的主要内容,如果未能解决你的问题,请参考以下文章

如何使用环境变量覆盖 ASP.NET Core 配置数组设置

在 ASP.NET Core 中读取环境变量

ASP.NET Core学习——7

如何在.net core web 中将 url 设置为 webapi?

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

如何在 ASP.NET CORE 5.0 MVC 中将登录设置为默认路由