diff --git a/src/libraries/Microsoft.Extensions.Configuration.EnvironmentVariables/src/EnvironmentVariablesConfigurationProvider.cs b/src/libraries/Microsoft.Extensions.Configuration.EnvironmentVariables/src/EnvironmentVariablesConfigurationProvider.cs index 8b88483620cc50..73e696f201b2c3 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.EnvironmentVariables/src/EnvironmentVariablesConfigurationProvider.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.EnvironmentVariables/src/EnvironmentVariablesConfigurationProvider.cs @@ -78,17 +78,9 @@ internal void Load(IDictionary envVariables) { prefix = CustomPrefix; } - else if (key.StartsWith(_prefix, StringComparison.OrdinalIgnoreCase)) - { - // This prevents the prefix from being normalized. - // We can also do a fast path branch, I guess? No point in reallocating if the prefix is empty. - key = NormalizeKey(key.Substring(_prefix.Length)); - data[key] = entry.Value as string; - - continue; - } else { + AddIfPrefixed(data, NormalizeKey(key), (string?)entry.Value); continue; } diff --git a/src/libraries/Microsoft.Extensions.Configuration.EnvironmentVariables/tests/EnvironmentVariablesTest.cs b/src/libraries/Microsoft.Extensions.Configuration.EnvironmentVariables/tests/EnvironmentVariablesTest.cs index c5b1030ee74a0b..1e98a5767096a0 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.EnvironmentVariables/tests/EnvironmentVariablesTest.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.EnvironmentVariables/tests/EnvironmentVariablesTest.cs @@ -166,7 +166,7 @@ public void ReplaceDoubleUnderscoreInEnvironmentVariablesButNotPrefix() envConfigSrc.Load(dict); - Assert.Equal("connection", envConfigSrc.Get("data:ConnectionString")); + Assert.Throws(() => envConfigSrc.Get("data:ConnectionString")); } [Fact] @@ -176,7 +176,7 @@ public void ReplaceDoubleUnderscoreInEnvironmentVariablesButNotInAnomalousPrefix { {"_____EXPERIMENTAL__data__ConnectionString", "connection"} }; - var envConfigSrc = new EnvironmentVariablesConfigurationProvider("_____EXPERIMENTAL__"); + var envConfigSrc = new EnvironmentVariablesConfigurationProvider("::_EXPERIMENTAL:"); envConfigSrc.Load(dict); @@ -194,7 +194,7 @@ public void ReplaceDoubleUnderscoreInEnvironmentVariablesWithDuplicatedPrefix() envConfigSrc.Load(dict); - Assert.Equal("connection", envConfigSrc.Get("test:ConnectionString")); + Assert.Throws(() => envConfigSrc.Get("test:ConnectionString")); } [Fact] @@ -205,7 +205,7 @@ public void PrefixPreventsLoadingSqlConnectionStrings() {"test__test__ConnectionString", "connection"}, {"SQLCONNSTR_db1", "connStr"} }; - var envConfigSrc = new EnvironmentVariablesConfigurationProvider("test__"); + var envConfigSrc = new EnvironmentVariablesConfigurationProvider("test:"); envConfigSrc.Load(dict); @@ -213,6 +213,54 @@ public void PrefixPreventsLoadingSqlConnectionStrings() Assert.Throws(() => envConfigSrc.Get("ConnectionStrings:db1_ProviderName")); } + public const string EnvironmentVariable = "Microsoft__Extensions__Configuration__EnvironmentVariables__Test__Foo"; + public class SettingsWithFoo + { + public string? Foo { get; set; } + } + + [Fact] + public void AddEnvironmentVariables_Bind_PrefixShouldNormalize() + { + try + { + Environment.SetEnvironmentVariable(EnvironmentVariable, "myFooValue"); + var configuration = new ConfigurationBuilder() + .AddEnvironmentVariables("Microsoft:Extensions:Configuration:EnvironmentVariables:Test:") + .Build(); + + var settingsWithFoo = new SettingsWithFoo(); + configuration.Bind(settingsWithFoo); + + Assert.Equal("myFooValue", settingsWithFoo.Foo); + } + finally + { + Environment.SetEnvironmentVariable(EnvironmentVariable, null); + } + } + + [Fact] + public void AddEnvironmentVariables_UsingDoubleUnderscores_Bind_PrefixWontNormalize() + { + try + { + Environment.SetEnvironmentVariable(EnvironmentVariable, "myFooValue"); + var configuration = new ConfigurationBuilder() + .AddEnvironmentVariables("Microsoft__Extensions__Configuration__EnvironmentVariables__Test__") + .Build(); + + var settingsWithFoo = new SettingsWithFoo(); + configuration.Bind(settingsWithFoo); + + Assert.Null(settingsWithFoo.Foo); + } + finally + { + Environment.SetEnvironmentVariable(EnvironmentVariable, null); + } + } + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] public void BindingDoesNotThrowIfReloadedDuringBinding() {