1515namespace Microsoft . FeatureManagement
1616{
1717 /// <summary>
18- /// A feature definition provider that pulls feature definitions from the .NET Core <see cref="IConfiguration"/> system.
18+ /// A feature definition provider that pulls feature flag definitions from the .NET Core <see cref="IConfiguration"/> system.
1919 /// </summary>
20- sealed class ConfigurationFeatureDefinitionProvider : IFeatureDefinitionProvider , IDisposable
20+ sealed class ConfigurationFeatureFlagDefinitionProvider : IFeatureFlagDefinitionProvider , IDisposable
2121 {
2222 private const string FeatureManagementSectionName = "FeatureManagement" ;
2323 private const string FeatureFlagDefinitionsSectionName = "FeatureFlags" ;
24- private const string DynamicFeatureDefinitionsSectionName = "DynamicFeatures" ;
2524 private const string FeatureFiltersSectionName = "EnabledFor" ;
26- private const string FeatureVariantsSectionName = "Variants" ;
2725 private readonly IConfiguration _configuration ;
2826 private readonly ConcurrentDictionary < string , FeatureFlagDefinition > _featureFlagDefinitions ;
29- private readonly ConcurrentDictionary < string , DynamicFeatureDefinition > _dynamicFeatureDefinitions ;
3027 private IDisposable _changeSubscription ;
3128 private int _stale = 0 ;
3229
33- public ConfigurationFeatureDefinitionProvider ( IConfiguration configuration )
30+ public ConfigurationFeatureFlagDefinitionProvider ( IConfiguration configuration )
3431 {
3532 _configuration = configuration ?? throw new ArgumentNullException ( nameof ( configuration ) ) ;
3633 _featureFlagDefinitions = new ConcurrentDictionary < string , FeatureFlagDefinition > ( ) ;
37- _dynamicFeatureDefinitions = new ConcurrentDictionary < string , DynamicFeatureDefinition > ( ) ;
3834
3935 _changeSubscription = ChangeToken . OnChange (
4036 ( ) => _configuration . GetReloadToken ( ) ,
@@ -83,41 +79,6 @@ public async IAsyncEnumerable<FeatureFlagDefinition> GetAllFeatureFlagDefinition
8379 }
8480 }
8581
86- public Task < DynamicFeatureDefinition > GetDynamicFeatureDefinitionAsync ( string featureName , CancellationToken cancellationToken = default )
87- {
88- if ( featureName == null )
89- {
90- throw new ArgumentNullException ( nameof ( featureName ) ) ;
91- }
92-
93- EnsureFresh ( ) ;
94-
95- //
96- // Query by feature name
97- DynamicFeatureDefinition definition = _dynamicFeatureDefinitions . GetOrAdd ( featureName , ( name ) => ReadDynamicFeatureDefinition ( name ) ) ;
98-
99- return Task . FromResult ( definition ) ;
100- }
101-
102- //
103- // The async key word is necessary for creating IAsyncEnumerable.
104- // The need to disable this warning occurs when implementaing async stream synchronously.
105- #pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously
106- public async IAsyncEnumerable < DynamicFeatureDefinition > GetAllDynamicFeatureDefinitionsAsync ( [ EnumeratorCancellation ] CancellationToken cancellationToken )
107- #pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously
108- {
109- EnsureFresh ( ) ;
110-
111- //
112- // Iterate over all features registered in the system at initial invocation time
113- foreach ( IConfigurationSection featureSection in GetDynamicFeatureDefinitionSections ( ) )
114- {
115- //
116- // Underlying IConfigurationSection data is dynamic so latest feature definitions are returned
117- yield return _dynamicFeatureDefinitions . GetOrAdd ( featureSection . Key , ( _ ) => ReadDynamicFeatureDefinition ( featureSection ) ) ;
118- }
119- }
120-
12182 private FeatureFlagDefinition ReadFeatureFlagDefinition ( string featureName )
12283 {
12384 IConfigurationSection configuration = GetFeatureFlagDefinitionSections ( )
@@ -131,19 +92,6 @@ private FeatureFlagDefinition ReadFeatureFlagDefinition(string featureName)
13192 return ReadFeatureFlagDefinition ( configuration ) ;
13293 }
13394
134- private DynamicFeatureDefinition ReadDynamicFeatureDefinition ( string featureName )
135- {
136- IConfigurationSection configuration = GetDynamicFeatureDefinitionSections ( )
137- . FirstOrDefault ( section => section . Key . Equals ( featureName , StringComparison . OrdinalIgnoreCase ) ) ;
138-
139- if ( configuration == null )
140- {
141- return null ;
142- }
143-
144- return ReadDynamicFeatureDefinition ( configuration ) ;
145- }
146-
14795 private FeatureFlagDefinition ReadFeatureFlagDefinition ( IConfigurationSection configurationSection )
14896 {
14997 /*
@@ -226,37 +174,15 @@ We support
226174 } ;
227175 }
228176
229- private DynamicFeatureDefinition ReadDynamicFeatureDefinition ( IConfigurationSection configurationSection )
230- {
231- Debug . Assert ( configurationSection != null ) ;
232-
233- var variants = new List < FeatureVariant > ( ) ;
234-
235- foreach ( IConfigurationSection section in configurationSection . GetSection ( FeatureVariantsSectionName ) . GetChildren ( ) )
236- {
237- if ( int . TryParse ( section . Key , out int _ ) && ! string . IsNullOrEmpty ( section [ nameof ( FeatureVariant . Name ) ] ) )
238- {
239- variants . Add ( new FeatureVariant
240- {
241- Default = section . GetValue < bool > ( nameof ( FeatureVariant . Default ) ) ,
242- Name = section . GetValue < string > ( nameof ( FeatureVariant . Name ) ) ,
243- ConfigurationReference = section . GetValue < string > ( nameof ( FeatureVariant . ConfigurationReference ) ) ,
244- AssignmentParameters = section . GetSection ( nameof ( FeatureVariant . AssignmentParameters ) )
245- } ) ;
246- }
247- }
248-
249- return new DynamicFeatureDefinition ( )
250- {
251- Name = configurationSection . Key ,
252- Variants = variants ,
253- Assigner = configurationSection . GetValue < string > ( nameof ( DynamicFeatureDefinition . Assigner ) )
254- } ;
255- }
256-
257177 private IEnumerable < IConfigurationSection > GetFeatureFlagDefinitionSections ( )
258178 {
259- IEnumerable < IConfigurationSection > featureManagementChildren = GetFeatureManagementSection ( ) . GetChildren ( ) ;
179+ //
180+ // Look for feature definitions under the "FeatureManagement" section
181+ IConfiguration featureManagementSection = _configuration . GetChildren ( ) . Any ( s => s . Key . Equals ( FeatureManagementSectionName , StringComparison . OrdinalIgnoreCase ) ) ?
182+ _configuration . GetSection ( FeatureManagementSectionName ) :
183+ _configuration ;
184+
185+ IEnumerable < IConfigurationSection > featureManagementChildren = featureManagementSection . GetChildren ( ) ;
260186
261187 IConfigurationSection featureFlagsSection = featureManagementChildren . FirstOrDefault ( s => s . Key == FeatureFlagDefinitionsSectionName ) ;
262188
@@ -266,29 +192,12 @@ private IEnumerable<IConfigurationSection> GetFeatureFlagDefinitionSections()
266192 featureManagementChildren :
267193 featureFlagsSection . GetChildren ( ) ;
268194 }
269-
270- private IEnumerable < IConfigurationSection > GetDynamicFeatureDefinitionSections ( )
271- {
272- return GetFeatureManagementSection ( )
273- . GetSection ( DynamicFeatureDefinitionsSectionName )
274- . GetChildren ( ) ;
275- }
276-
277- private IConfiguration GetFeatureManagementSection ( )
278- {
279- //
280- // Look for feature definitions under the "FeatureManagement" section
281- return _configuration . GetChildren ( ) . Any ( s => s . Key . Equals ( FeatureManagementSectionName , StringComparison . OrdinalIgnoreCase ) ) ?
282- _configuration . GetSection ( FeatureManagementSectionName ) :
283- _configuration ;
284- }
285195
286196 private void EnsureFresh ( )
287197 {
288198 if ( Interlocked . Exchange ( ref _stale , 0 ) != 0 )
289199 {
290200 _featureFlagDefinitions . Clear ( ) ;
291- _dynamicFeatureDefinitions . Clear ( ) ;
292201 }
293202 }
294203 }
0 commit comments