.Net Core ConfigureAppConfiguration 添加额外的资源覆盖环境特定设置
.Net Core ConfigureAppConfiguration adding additional sources overriding environment specific settings
在带有通用主机的 .NET Core 2.1 应用程序中使用 IConfigurationBuilder 时,我配置了 4 个源;但在 ConfigureAppConfiguration 的范围之后有 6 个来源。
在某些时候,我已经加载的 2 个额外源被第二次添加,导致 appsettings.Environment.json 值被隐藏。我还尝试删除 hostsettings.json 配置并验证这不会影响这一点。
这是针对使用 WebjobsSDK 3.0 和 .Net Core 2.1
的 Azure Webjob
var builder = new HostBuilder()
.ConfigureHostConfiguration(configurationBuilder =>
{
//This is to do some basic host configuration and should only add 2 sources
configurationBuilder.SetBasePath(Directory.GetCurrentDirectory());
configurationBuilder.AddJsonFile("hostsettings.json", optional: true);
configurationBuilder.AddEnvironmentVariables(prefix: "APPSETTING_ASPNETCORE_");
})
.ConfigureAppConfiguration((hostContext, configurationBuilder) =>
{
//at this point there are 0 sources in the sources
IHostingEnvironment env = hostContext.HostingEnvironment;
configurationBuilder.SetBasePath(Directory.GetCurrentDirectory());
configurationBuilder.AddJsonFile("appSettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appSettings.{env.EnvironmentName}.json", optional: true,
reloadOnChange: true);
configurationBuilder.AddEnvironmentVariables(prefix: "APPSETTING_ASPNETCORE_");
//at this point there are 4 sources
})
.ConfigureServices((hostContext, servicesCollection) =>
{
//now there are 6, 2 additional source that are duplicates
servicesCollection.Configure<IConfiguration>(hostContext.Configuration);
})
我希望配置提供程序只有 4 个源,包括 ChainedConfigSource,我已经设置好了。但是添加了 2 个额外的源,它们是 appsettings.json 和我在加载特定环境 appsettings.environment.json.
之前声明的环境变量的副本
现在,当注入 class 时,最后添加的 appsettings.json 设置会通过 appsettings.environment.json
返回
阅读 Hostbuilder.cs class 的源代码,您将看到在 AddHostingConfiguration 中添加的配置被添加到 ApplicationConfiguration。
找到来源
构建调用将首先创建 HostingConfiguration,然后是 AppConfiguration。
这是构建 HostingConfiguration
的代码
private void BuildHostConfiguration()
{
var configBuilder = new ConfigurationBuilder();
foreach (var buildAction in _configureHostConfigActions)
{
buildAction(configBuilder);
}
_hostConfiguration = configBuilder.Build();
}
现在,在 BuildAppConfiguration 中,您将看到 HostingConfiguration 添加到 AppConfiguration 之上
private void BuildAppConfiguration()
{
var configBuilder = new ConfigurationBuilder();
//Here _hostConfiguration gets added ontop
configBuilder.AddConfiguration(_hostConfiguration);
foreach (var buildAction in _configureAppConfigActions)
{
buildAction(_hostBuilderContext, configBuilder);
}
_appConfiguration = configBuilder.Build();
_hostBuilderContext.Configuration = _appConfiguration;
}
现在构建函数是私有的,无法 reset/clear 来自构建器的源代码。
如果您不想实现自己的 HostBuilder 版本,我建议您不要将主机设置与 App 设置分开
因此,根据文档,WebHostBuilder 会为您加载 appSettings.json 和 appSettings.env.json 文件。但它并没有说明 HostBuilder 也这样做,我认为这是由于缺乏文档,我无法确定源代码的来源。
为了解决这个问题,我更改了配置文件的设置方式。以前我在 appSettings.json 文件和 appSettings.env.json 文件中都有连接字符串。所以我遇到了最后添加的配置文件替换基本配置文件中的值的问题。我现在已将基于环境的设置仅移动到每个环境的配置文件中,并且仅将对所有环境全局的设置保留在基本配置文件中。
似乎 .NET 框架配置转换设置的旧习惯很难改掉。我无法确定是否应将从多个提供程序声明的 IConfiguration 中的相同键更改为最后加载的提供程序,我认为一些文档涵盖了这一点并确认了这一点,但现在我找不到它。
But 2 additional sources are added which are duplicates of the appsettings.json
and the environment variables
我在使用 HostBuilder
的 Azure WebJob 中遇到了类似的问题,并注意到这两个源已附加到配置源列表的末尾。这产生了不良结果:appsettings.json
的开发设置覆盖了 appsettings.Production.json
.
的生产设置
这些额外的来源 appear to be added here 来自 ConfigureWebJobs
。
解决方法是重新排序 HostBuilder
调用链,以便对 ConfigureWebJobs
的调用在对 ConfigureAppConfiguration
的调用之前 .这两个额外的源仍然存在,但由于它们现在位于配置源列表的开头,而不是末尾,因此它们没有不良影响。
可以重新排序 builder.Sources
以满足您的需要。例如,这里有一个扩展方法,您可以使用它在最后一个文件之后添加一个新的 JSON 文件,而不是在最后:
public static class ConfigurationBuilderExtensions
{
public static IConfigurationBuilder AddJsonFileAfterLastJsonFile(this IConfigurationBuilder builder, string path, bool optional, bool reloadOnChange)
{
var jsonFileSource = new JsonConfigurationSource
{
FileProvider = null,
Path = path,
Optional = optional,
ReloadOnChange = reloadOnChange
};
jsonFileSource.ResolveFileProvider();
var lastJsonFileSource = builder.Sources.LastOrDefault(s => s is JsonConfigurationSource);
var indexOfLastJsonFileSource = builder.Sources.IndexOf(lastJsonFileSource);
builder.Sources.Insert(indexOfLastJsonFileSource == -1
? builder.Sources.Count
: indexOfLastJsonFileSource + 1, jsonFileSource);
return builder;
}
}
然后您可以像这样使用它:
.ConfigureAppConfiguration((hostingContext, config) =>
{
config.AddJsonFileAfterLastJsonFile(
"appsettings.Custom.json",
optional: true,
reloadOnChange: false);
})
您可以根据需要调整它,并将其插入到您需要的任何地方。
在带有通用主机的 .NET Core 2.1 应用程序中使用 IConfigurationBuilder 时,我配置了 4 个源;但在 ConfigureAppConfiguration 的范围之后有 6 个来源。
在某些时候,我已经加载的 2 个额外源被第二次添加,导致 appsettings.Environment.json 值被隐藏。我还尝试删除 hostsettings.json 配置并验证这不会影响这一点。 这是针对使用 WebjobsSDK 3.0 和 .Net Core 2.1
的 Azure Webjob var builder = new HostBuilder()
.ConfigureHostConfiguration(configurationBuilder =>
{
//This is to do some basic host configuration and should only add 2 sources
configurationBuilder.SetBasePath(Directory.GetCurrentDirectory());
configurationBuilder.AddJsonFile("hostsettings.json", optional: true);
configurationBuilder.AddEnvironmentVariables(prefix: "APPSETTING_ASPNETCORE_");
})
.ConfigureAppConfiguration((hostContext, configurationBuilder) =>
{
//at this point there are 0 sources in the sources
IHostingEnvironment env = hostContext.HostingEnvironment;
configurationBuilder.SetBasePath(Directory.GetCurrentDirectory());
configurationBuilder.AddJsonFile("appSettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appSettings.{env.EnvironmentName}.json", optional: true,
reloadOnChange: true);
configurationBuilder.AddEnvironmentVariables(prefix: "APPSETTING_ASPNETCORE_");
//at this point there are 4 sources
})
.ConfigureServices((hostContext, servicesCollection) =>
{
//now there are 6, 2 additional source that are duplicates
servicesCollection.Configure<IConfiguration>(hostContext.Configuration);
})
我希望配置提供程序只有 4 个源,包括 ChainedConfigSource,我已经设置好了。但是添加了 2 个额外的源,它们是 appsettings.json 和我在加载特定环境 appsettings.environment.json.
之前声明的环境变量的副本现在,当注入 class 时,最后添加的 appsettings.json 设置会通过 appsettings.environment.json
返回阅读 Hostbuilder.cs class 的源代码,您将看到在 AddHostingConfiguration 中添加的配置被添加到 ApplicationConfiguration。
找到来源构建调用将首先创建 HostingConfiguration,然后是 AppConfiguration。
这是构建 HostingConfiguration
的代码 private void BuildHostConfiguration()
{
var configBuilder = new ConfigurationBuilder();
foreach (var buildAction in _configureHostConfigActions)
{
buildAction(configBuilder);
}
_hostConfiguration = configBuilder.Build();
}
现在,在 BuildAppConfiguration 中,您将看到 HostingConfiguration 添加到 AppConfiguration 之上
private void BuildAppConfiguration()
{
var configBuilder = new ConfigurationBuilder();
//Here _hostConfiguration gets added ontop
configBuilder.AddConfiguration(_hostConfiguration);
foreach (var buildAction in _configureAppConfigActions)
{
buildAction(_hostBuilderContext, configBuilder);
}
_appConfiguration = configBuilder.Build();
_hostBuilderContext.Configuration = _appConfiguration;
}
现在构建函数是私有的,无法 reset/clear 来自构建器的源代码。
如果您不想实现自己的 HostBuilder 版本,我建议您不要将主机设置与 App 设置分开
因此,根据文档,WebHostBuilder 会为您加载 appSettings.json 和 appSettings.env.json 文件。但它并没有说明 HostBuilder 也这样做,我认为这是由于缺乏文档,我无法确定源代码的来源。
为了解决这个问题,我更改了配置文件的设置方式。以前我在 appSettings.json 文件和 appSettings.env.json 文件中都有连接字符串。所以我遇到了最后添加的配置文件替换基本配置文件中的值的问题。我现在已将基于环境的设置仅移动到每个环境的配置文件中,并且仅将对所有环境全局的设置保留在基本配置文件中。
似乎 .NET 框架配置转换设置的旧习惯很难改掉。我无法确定是否应将从多个提供程序声明的 IConfiguration 中的相同键更改为最后加载的提供程序,我认为一些文档涵盖了这一点并确认了这一点,但现在我找不到它。
But 2 additional sources are added which are duplicates of the
appsettings.json
and the environment variables
我在使用 HostBuilder
的 Azure WebJob 中遇到了类似的问题,并注意到这两个源已附加到配置源列表的末尾。这产生了不良结果:appsettings.json
的开发设置覆盖了 appsettings.Production.json
.
这些额外的来源 appear to be added here 来自 ConfigureWebJobs
。
解决方法是重新排序 HostBuilder
调用链,以便对 ConfigureWebJobs
的调用在对 ConfigureAppConfiguration
的调用之前 .这两个额外的源仍然存在,但由于它们现在位于配置源列表的开头,而不是末尾,因此它们没有不良影响。
可以重新排序 builder.Sources
以满足您的需要。例如,这里有一个扩展方法,您可以使用它在最后一个文件之后添加一个新的 JSON 文件,而不是在最后:
public static class ConfigurationBuilderExtensions
{
public static IConfigurationBuilder AddJsonFileAfterLastJsonFile(this IConfigurationBuilder builder, string path, bool optional, bool reloadOnChange)
{
var jsonFileSource = new JsonConfigurationSource
{
FileProvider = null,
Path = path,
Optional = optional,
ReloadOnChange = reloadOnChange
};
jsonFileSource.ResolveFileProvider();
var lastJsonFileSource = builder.Sources.LastOrDefault(s => s is JsonConfigurationSource);
var indexOfLastJsonFileSource = builder.Sources.IndexOf(lastJsonFileSource);
builder.Sources.Insert(indexOfLastJsonFileSource == -1
? builder.Sources.Count
: indexOfLastJsonFileSource + 1, jsonFileSource);
return builder;
}
}
然后您可以像这样使用它:
.ConfigureAppConfiguration((hostingContext, config) =>
{
config.AddJsonFileAfterLastJsonFile(
"appsettings.Custom.json",
optional: true,
reloadOnChange: false);
})
您可以根据需要调整它,并将其插入到您需要的任何地方。