在.NET Core中合并appsettings和环境变量

29

我正在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/v{version: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到问题中?如果您能提供两个版本,一个是包含env文件的,另一个是将env分别列出的,那就太好了。非常感谢! - AD8
1个回答

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

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

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

{
  "Logging": {
      "Level": "Debug"
  }
}

通过将名为Logging:Level的环境变量设置为所选值,您可以覆盖Logging.Level的值。

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

还要注意:文档中提到:

如果在您的系统中无法使用冒号(:)作为环境变量名称,请使用双下划线(__)替换冒号(:)。


4
双下划线真的解决了我在Docker中的环境变量问题。 - Dar
双下划线确实是最好的选择...尤其是在部署到 Azure 容器实例时,您想要传递嵌套配置值的情况下。 - Wim Van Houts
1
这个链的顺序会影响哪个源具有优先权吗?如果我们将上面的代码重新排列为 config.AddEnvironmentVariables().AddJsonFile("appsettings.json").AddJsonFile($"appsettings.docker.json", true);,那么在 appsettings.docker.json 中存在的值是否会优先于其他两个源中的值,因为它是最后调用的? - Collin Barrett
2
我刚被点到了,如果不把 AddEnvironmentVariables() 方法放在最后一行调用,就会出问题!!! - Oly Dungey
1
你能否添加一个appsettings文件和dockerfile的示例,以便完整呈现?这将有助于人们(像我一样)更轻松地理解实际设置。如果您能够添加一个docker命令示例,展示如何运行该镜像并设置变量,那就太好了。谢谢。 - AD8

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接