是否有一种“开箱即用”的方法来自动扩展appsettings.json
值中的环境变量?
举一个人为的例子:
{
...
"MyPath1": "C:/MyApp/%ENV%/Myfolder1/MyFile1.dat",
"MyConnectionString": "Server=MyServer%ENV%..."
...
}
我的目标是能够通过更改单个环境变量来切换我的环境,并使其影响多个应用程序设置值,而不是具有每个环境的配置文件。
更新
我已经浏览了the source code of JsonConfigurationProvider,据我所知,没有开箱即用的功能。
我看到应该可以通过从JsonConfigurationProvider
派生自定义类并覆盖Load()
方法来实现:
public override void Load()
{
base.Load();
foreach(var key in Data.Keys)
{
Data[key] = Environment.ExpandEnvironmentVariables(key);
}
}
但是我对.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?
}
);
答案 0 :(得分:3)
要创建和使用自定义配置源,需要两个实现:
将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));
}
}
这里没有很多事情。这些实现仅遵循与现有JsonConfigurationSource
和JsonConfigurationProvider
实现相同的方法,并具有用于扩展环境变量的自定义处理。
要替换基于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
});
}
});
传入ConfigureAppConfiguration
的委托执行以下操作:
JsonConfigurationSource
的所有已配置实例。应该有两个实例:appsettings.json
和例如appsettings.Development.json
。对于每个实例:
ExpandJsonConfigurationSource
替换已删除的实例,在属性之间进行复制以确保其具有相同的路径,可选标志等。答案 1 :(得分:1)
我创建了一个库来执行变量替换,它从任何配置源进行替换,而不仅仅是环境变量。 参见:https://github.com/molinch/ConfigurationSubstitutor
您只需要将其注册为另一个配置源,即可通过在ConfigurationBuilder上调用.EnableSubstitutions()
来完成。
以您的示例为例:
"MyPath": "C:/MyApp/%ENV%/Myfolder1/MyFile1.dat"
ENV = Foo
.EnableSubstitutions("%", "%")
最后,从配置请求MyPath时,您将获得:C:/MyApp/Foo/Myfolder1/MyFile1.dat