diff --git a/src/Configuration/Config.KeyPerFile/src/KeyPerFileConfigurationProvider.cs b/src/Configuration/Config.KeyPerFile/src/KeyPerFileConfigurationProvider.cs index 474889574411..6e4234ecf3c3 100644 --- a/src/Configuration/Config.KeyPerFile/src/KeyPerFileConfigurationProvider.cs +++ b/src/Configuration/Config.KeyPerFile/src/KeyPerFileConfigurationProvider.cs @@ -31,12 +31,13 @@ private static string TrimNewLine(string value) /// public override void Load() { - Data = new Dictionary(StringComparer.OrdinalIgnoreCase); + var data = new Dictionary(StringComparer.OrdinalIgnoreCase); if (Source.FileProvider == null) { if (Source.Optional) { + Data = data; return; } else @@ -63,10 +64,12 @@ public override void Load() { if (Source.IgnoreCondition == null || !Source.IgnoreCondition(file.Name)) { - Data.Add(NormalizeKey(file.Name), TrimNewLine(streamReader.ReadToEnd())); + data.Add(NormalizeKey(file.Name), TrimNewLine(streamReader.ReadToEnd())); } } } + + Data = data; } } } diff --git a/src/Configuration/Config.KeyPerFile/test/KeyPerFileTests.cs b/src/Configuration/Config.KeyPerFile/test/KeyPerFileTests.cs index d409c0eab087..499c25106c86 100644 --- a/src/Configuration/Config.KeyPerFile/test/KeyPerFileTests.cs +++ b/src/Configuration/Config.KeyPerFile/test/KeyPerFileTests.cs @@ -4,6 +4,8 @@ using System.IO; using System.Linq; using System.Text; +using System.Threading; +using System.Threading.Tasks; using Microsoft.Extensions.FileProviders; using Microsoft.Extensions.Primitives; using Xunit; @@ -177,6 +179,39 @@ public void CanUnIgnoreDefaultFiles() Assert.Equal("SecretValue1", config["ignore.Secret1"]); Assert.Equal("SecretValue2", config["Secret2"]); } + + [Fact] + public void BindingDoesNotThrowIfReloadedDuringBinding() + { + var testFileProvider = new TestFileProvider( + new TestFile("Number", "-2"), + new TestFile("Text", "Foo")); + + var config = new ConfigurationBuilder() + .AddKeyPerFile(o => o.FileProvider = testFileProvider) + .Build(); + + MyOptions options = null; + + using (var cts = new CancellationTokenSource(TimeSpan.FromMilliseconds(250))) + { + _ = Task.Run(() => { while (!cts.IsCancellationRequested) config.Reload(); }); + + while (!cts.IsCancellationRequested) + { + options = config.Get(); + } + } + + Assert.Equal(-2, options.Number); + Assert.Equal("Foo", options.Text); + } + + private sealed class MyOptions + { + public int Number { get; set; } + public string Text { get; set; } + } } class TestFileProvider : IFileProvider diff --git a/src/Configuration/Config.KeyPerFile/test/Microsoft.Extensions.Configuration.KeyPerFile.Tests.csproj b/src/Configuration/Config.KeyPerFile/test/Microsoft.Extensions.Configuration.KeyPerFile.Tests.csproj index 4205f4ae1357..154fd5bb6219 100644 --- a/src/Configuration/Config.KeyPerFile/test/Microsoft.Extensions.Configuration.KeyPerFile.Tests.csproj +++ b/src/Configuration/Config.KeyPerFile/test/Microsoft.Extensions.Configuration.KeyPerFile.Tests.csproj @@ -5,6 +5,7 @@ +