在 appSettings.json 文件中展开环境变量

Joe*_*Joe 7 c# .net-core asp.net-core asp.net-core-2.1

有没有一种“开箱即用”的方法来appsettings.json自动扩展值中的环境变量?

举一个人为的例子:

{
  ...
  "MyPath1": "C:/MyApp/%ENV%/Myfolder1/MyFile1.dat",
  "MyConnectionString":  "Server=MyServer%ENV%..."
  ...
}
Run Code Online (Sandbox Code Playgroud)

我的目标是能够通过更改单个环境变量来切换我的环境,并使其影响多个 appsetting 值,而不是具有每个环境的配置文件。

更新

我查看了 JsonConfigurationProvider 的源代码,据我所知,没有开箱即用的功能。

我可以看到通过从JsonConfigurationProviderLoad()方法派生自定义类并覆盖该方法应该是可能的:

public override void Load()
{
    base.Load();
    foreach(var key in Data.Keys)
    {
        Data[key] = Environment.ExpandEnvironmentVariables(key);
    }
}
Run Code Online (Sandbox Code Playgroud)

但是我对 .NET Core 配置很陌生,这导致了第二个问题:

我如何获得这个自定义实现来替换标准实现?即删除默认的 appsettings.json 和 appsettings.environment.json 提供程序并替换为自定义的。大概要添加的东西Program.cs

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>()
        .ConfigureAppConfiguration(config =>
        {
            config.??? what do I need here?
        }
        );
Run Code Online (Sandbox Code Playgroud)

Fab*_*ien 8

我创建了一个库来执行变量替换,它可以从任何配置源替换,而不仅仅是环境变量。看: https: //github.com/molinch/ConfigurationSubstitutor

您只需将其注册为另一个配置源,这是通过调用.EnableSubstitutions()ConfigurationBuilder 来完成的。

以你的例子:

  • 如果在 appsettings.json 中你有:"MyPath": "C:/MyApp/%ENV%/Myfolder1/MyFile1.dat"
  • 并且您有以下环境变量:ENV = Foo
  • 那么你应该启用替换:
.EnableSubstitutions("%", "%")
Run Code Online (Sandbox Code Playgroud)

最后,当从配置中请求 MyPath 时,您将得到:C:/MyApp/Foo/Myfolder1/MyFile1.dat


Kir*_*kin 5

要创建和使用自定义配置源,需要两个实现:

  1. IConfigurationSource
  2. IConfigurationProvider

这是IConfigurationSource添加到IConfigurationBuilder的源的实现。此实现还负责创建自己的IConfigurationProvider,负责从源加载数据。

这是IConfigurationSource( ExpandJsonConfigurationSource) 和IConfigurationProvider( ExpandJsonConfigurationProvider)的自定义实现:

public class ExpandJsonConfigurationSource : JsonConfigurationSource
{
    public override IConfigurationProvider Build(IConfigurationBuilder builder)
    {
        EnsureDefaults(builder);
        return new ExpandJsonConfigurationProvider(this);
    }
}

public class ExpandJsonConfigurationProvider : JsonConfigurationProvider
{
    public ExpandJsonConfigurationProvider(ExpandJsonConfigurationSource source)
        : base(source) { }

    public override void Load()
    {
        base.Load();
        Data = Data.ToDictionary(
            x => x.Key,
            x => Environment.ExpandEnvironmentVariables(x.Value),
            StringComparer.OrdinalIgnoreCase);
    }
}
Run Code Online (Sandbox Code Playgroud)

这里没有太多事情发生。这些实现只是遵循与现有JsonConfigurationSourceJsonConfigurationProvider实现相同的方法,带有用于扩展环境变量的自定义处理。

要替换预配置的基于 JSON 的源,请使用以下命令:

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>()
        .ConfigureAppConfiguration((ctx, builder) =>
        {
            var jsonConfigurationSources = builder.Sources
                .OfType<JsonConfigurationSource>()
                .ToList();

            foreach (var jsonConfigurationSource in jsonConfigurationSources)
            {
                var indexOfJsonConfigurationSource = builder.Sources
                    .IndexOf(jsonConfigurationSource);

                builder.Sources.RemoveAt(indexOfJsonConfigurationSource);
                builder.Sources.Insert(
                    indexOfJsonConfigurationSource,
                    new ExpandJsonConfigurationSource
                    {
                        FileProvider = jsonConfigurationSource.FileProvider,
                        Path = jsonConfigurationSource.Path,
                        Optional = jsonConfigurationSource.Optional,
                        ReloadOnChange = jsonConfigurationSource.ReloadOnChange
                    });
            }
        });
Run Code Online (Sandbox Code Playgroud)

传入的委托ConfigureAppConfiguration执行以下操作:

  1. 找到所有已配置的JsonConfigurationSource. 应该有两个实例: forappsettings.json和 for eg appsettings.Development.json

  2. 对于每个实例:

  3. 确定实例在预配置源中的位置。

  4. 删除实例。

  5. 将删除的实例替换为 的实例ExpandJsonConfigurationSource,跨属性复制以确保它具有相同的路径、可选标志等。