diff --git a/src/Microsoft.FeatureManagement/ConfigurationFeatureDefinitionProvider.cs b/src/Microsoft.FeatureManagement/ConfigurationFeatureDefinitionProvider.cs index 4774fd5e..276f4822 100644 --- a/src/Microsoft.FeatureManagement/ConfigurationFeatureDefinitionProvider.cs +++ b/src/Microsoft.FeatureManagement/ConfigurationFeatureDefinitionProvider.cs @@ -2,6 +2,7 @@ // Licensed under the MIT license. // using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; using Microsoft.Extensions.Primitives; using System; using System.Collections.Concurrent; @@ -23,14 +24,17 @@ sealed class ConfigurationFeatureDefinitionProvider : IFeatureDefinitionProvider private const string FeatureFiltersSectionName = "EnabledFor"; private const string RequirementTypeKeyword = "RequirementType"; + private const string FeatureManagementSectionName = "FeatureManagement"; private readonly IConfiguration _configuration; private readonly ConcurrentDictionary _definitions; private IDisposable _changeSubscription; + private readonly ILogger _logger; private int _stale = 0; - public ConfigurationFeatureDefinitionProvider(IConfiguration configuration) + public ConfigurationFeatureDefinitionProvider(IConfiguration configuration, ILoggerFactory loggerFactory) { _configuration = configuration ?? throw new ArgumentNullException(nameof(configuration)); + _logger = loggerFactory?.CreateLogger() ?? throw new ArgumentNullException(nameof(loggerFactory)); _definitions = new ConcurrentDictionary(); _changeSubscription = ChangeToken.OnChange( @@ -199,18 +203,18 @@ We support private IEnumerable GetFeatureDefinitionSections() { - const string FeatureManagementSectionName = "FeatureManagement"; + // + // Look for feature definitions under the "FeatureManagement" section + IConfigurationSection featureManagementConfigurationSection = _configuration.GetSection(FeatureManagementSectionName); - if (_configuration.GetChildren().Any(s => s.Key.Equals(FeatureManagementSectionName, StringComparison.OrdinalIgnoreCase))) + if (featureManagementConfigurationSection.Exists()) { - // - // Look for feature definitions under the "FeatureManagement" section - return _configuration.GetSection(FeatureManagementSectionName).GetChildren(); - } - else - { - return _configuration.GetChildren(); + return featureManagementConfigurationSection.GetChildren(); } + + _logger.LogDebug($"No configuration section named '{FeatureManagementSectionName}' was found."); + + return Enumerable.Empty(); } } } diff --git a/src/Microsoft.FeatureManagement/ServiceCollectionExtensions.cs b/src/Microsoft.FeatureManagement/ServiceCollectionExtensions.cs index 507f1394..04cbb499 100644 --- a/src/Microsoft.FeatureManagement/ServiceCollectionExtensions.cs +++ b/src/Microsoft.FeatureManagement/ServiceCollectionExtensions.cs @@ -4,6 +4,7 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; +using Microsoft.Extensions.Logging; using System; namespace Microsoft.FeatureManagement @@ -48,7 +49,7 @@ public static IFeatureManagementBuilder AddFeatureManagement(this IServiceCollec throw new ArgumentNullException(nameof(configuration)); } - services.AddSingleton(new ConfigurationFeatureDefinitionProvider(configuration)); + services.AddSingleton(sp => new ConfigurationFeatureDefinitionProvider(configuration, sp.GetRequiredService())); return services.AddFeatureManagement(); } diff --git a/tests/Tests.FeatureManagement/FeatureManagement.cs b/tests/Tests.FeatureManagement/FeatureManagement.cs index 9ecd3e7f..84f18b5e 100644 --- a/tests/Tests.FeatureManagement/FeatureManagement.cs +++ b/tests/Tests.FeatureManagement/FeatureManagement.cs @@ -12,9 +12,11 @@ using Microsoft.FeatureManagement.FeatureFilters; using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Net; using System.Net.Http; +using System.Text; using System.Threading.Tasks; using Xunit; @@ -71,6 +73,30 @@ public async Task ReadsConfiguration() Assert.True(called); } + [Fact] + public async Task ReadsOnlyFeatureManagementSection() + { + MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes("{\"AllowedHosts\": \"*\"}")); + IConfiguration config = new ConfigurationBuilder().AddJsonStream(stream).Build(); + + var services = new ServiceCollection(); + + services + .AddSingleton(config) + .AddFeatureManagement() + .AddFeatureFilter(); + + ServiceProvider serviceProvider = services.BuildServiceProvider(); + + IFeatureManager featureManager = serviceProvider.GetRequiredService(); + + await foreach (string featureName in featureManager.GetFeatureNamesAsync()) + { + // Fail, as no features should be found + Assert.True(false); + } + } + [Fact] public async Task Integrates() { diff --git a/tests/Tests.FeatureManagement/Tests.FeatureManagement.csproj b/tests/Tests.FeatureManagement/Tests.FeatureManagement.csproj index 7501c259..83063e1c 100644 --- a/tests/Tests.FeatureManagement/Tests.FeatureManagement.csproj +++ b/tests/Tests.FeatureManagement/Tests.FeatureManagement.csproj @@ -16,7 +16,7 @@ - +