diff --git a/src/libraries/Microsoft.Extensions.Configuration.Abstractions/ref/Microsoft.Extensions.Configuration.Abstractions.cs b/src/libraries/Microsoft.Extensions.Configuration.Abstractions/ref/Microsoft.Extensions.Configuration.Abstractions.cs index 74cdd5589db98..c743a37346c22 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Abstractions/ref/Microsoft.Extensions.Configuration.Abstractions.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Abstractions/ref/Microsoft.Extensions.Configuration.Abstractions.cs @@ -13,6 +13,7 @@ public static partial class ConfigurationExtensions public static System.Collections.Generic.IEnumerable> AsEnumerable(this Microsoft.Extensions.Configuration.IConfiguration configuration, bool makePathsRelative) { throw null; } public static bool Exists(this Microsoft.Extensions.Configuration.IConfigurationSection section) { throw null; } public static string GetConnectionString(this Microsoft.Extensions.Configuration.IConfiguration configuration, string name) { throw null; } + public static Microsoft.Extensions.Configuration.IConfigurationSection GetRequiredSection(this Microsoft.Extensions.Configuration.IConfiguration configuration, string key) { throw null; } } public static partial class ConfigurationPath { diff --git a/src/libraries/Microsoft.Extensions.Configuration.Abstractions/src/ConfigurationExtensions.cs b/src/libraries/Microsoft.Extensions.Configuration.Abstractions/src/ConfigurationExtensions.cs index ae620c77c2dd4..0618e9b018e41 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Abstractions/src/ConfigurationExtensions.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Abstractions/src/ConfigurationExtensions.cs @@ -81,5 +81,31 @@ public static bool Exists(this IConfigurationSection section) } return section.Value != null || section.GetChildren().Any(); } + + /// + /// Gets a configuration sub-section with the specified key. + /// + /// + /// The key of the configuration section. + /// The . + /// + /// If no matching sub-section is found with the specified key, an exception is raised. + /// + /// There is no section with key . + public static IConfigurationSection GetRequiredSection(this IConfiguration configuration, string key) + { + if (configuration == null) + { + throw new ArgumentNullException(nameof(configuration)); + } + + IConfigurationSection section = configuration.GetSection(key); + if (section.Exists()) + { + return section; + } + + throw new InvalidOperationException(SR.Format(SR.InvalidSectionName, key)); + } } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Abstractions/src/Resources/Strings.resx b/src/libraries/Microsoft.Extensions.Configuration.Abstractions/src/Resources/Strings.resx new file mode 100644 index 0000000000000..44a3123024f0b --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Configuration.Abstractions/src/Resources/Strings.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Section '{0}' not found in configuration. + + \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.Configuration/tests/ConfigurationTest.cs b/src/libraries/Microsoft.Extensions.Configuration/tests/ConfigurationTest.cs index 40f2b23a9051f..a2f1a09794ddd 100644 --- a/src/libraries/Microsoft.Extensions.Configuration/tests/ConfigurationTest.cs +++ b/src/libraries/Microsoft.Extensions.Configuration/tests/ConfigurationTest.cs @@ -744,6 +744,53 @@ public void SectionWithValueExists() Assert.False(sectionNotExists); } + [Fact] + public void SectionGetRequiredSectionSuccess() + { + // Arrange + var dict = new Dictionary() + { + {"Mem1", "Value1"}, + {"Mem1:KeyInMem1", "ValueInMem1"}, + {"Mem1:KeyInMem1:Deep1", "ValueDeep1"} + }; + var configurationBuilder = new ConfigurationBuilder(); + configurationBuilder.AddInMemoryCollection(dict); + IConfigurationRoot config = configurationBuilder.Build(); + + // Act + var sectionExists1 = config.GetRequiredSection("Mem1").Exists(); + var sectionExists2 = config.GetRequiredSection("Mem1:KeyInMem1").Exists(); + + // Assert + Assert.True(sectionExists1); + Assert.True(sectionExists2); + } + + [Fact] + public void SectionGetRequiredSectionMissingThrowException() + { + // Arrange + var dict = new Dictionary() + { + {"Mem1", "Value1"}, + {"Mem1:Deep1", "Value1"}, + }; + var configurationBuilder = new ConfigurationBuilder(); + configurationBuilder.AddInMemoryCollection(dict); + IConfigurationRoot config = configurationBuilder.Build(); + + Assert.Throws(() => config.GetRequiredSection("Mem2")); + Assert.Throws(() => config.GetRequiredSection("Mem1:Deep2")); + } + + [Fact] + public void SectionGetRequiredSectionNullThrowException() + { + IConfigurationRoot config = null; + Assert.Throws(() => config.GetRequiredSection("Mem1")); + } + [Fact] public void SectionWithChildrenExists() {