Skip to content

Commit d2aca88

Browse files
Enable missing feature switch
1 parent 711c56e commit d2aca88

File tree

4 files changed

+77
-1
lines changed

4 files changed

+77
-1
lines changed

src/Microsoft.FeatureManagement/FeatureManagementError.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@ public enum FeatureManagementError
1616
/// <summary>
1717
/// A feature filter configured for the feature being evaluated is an ambiguous reference to multiple registered feature filters.
1818
/// </summary>
19-
AmbiguousFeatureFilter
19+
AmbiguousFeatureFilter,
20+
21+
/// <summary>
22+
/// A feature filter is missing configuration
23+
/// </summary>
24+
MissingFeature
2025
}
2126
}

src/Microsoft.FeatureManagement/FeatureManagementOptions.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,11 @@ public class FeatureManagementOptions
1313
/// If missing feature filters are not ignored an exception will be thrown when attempting to evaluate a feature that depends on a missing feature filter.
1414
/// </summary>
1515
public bool IgnoreMissingFeatureFilters { get; set; }
16+
17+
/// <summary>
18+
/// Controls the behavior of feature evaluation when the dependent feature declaration is missing.
19+
/// If missing feature declaration is not ignored an exception will be thrown when attempting to evaluate a feature that depends on a missing feature declaration.
20+
/// </summary>
21+
public bool IgnoreMissingFeatures { get; set; }
1622
}
1723
}

src/Microsoft.FeatureManagement/FeatureManager.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,9 @@ private async Task<bool> IsEnabledAsync<TContext>(string feature, TContext appCo
140140
}
141141
}
142142
}
143+
} else if (!_options.IgnoreMissingFeatures)
144+
{
145+
throw new FeatureManagementException(FeatureManagementError.MissingFeature, $"The feature declaration for specified feature '{feature}' was not found.");
143146
}
144147

145148
foreach (ISessionManager sessionManager in _sessionManagers)

tests/Tests.FeatureManagement/FeatureManagement.cs

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
using System.Linq;
1515
using System.Net;
1616
using System.Net.Http;
17+
using System.Reflection;
1718
using System.Threading.Tasks;
1819
using Xunit;
1920

@@ -25,6 +26,7 @@ public class FeatureManagement
2526
private const string OffFeature = "OffFeature";
2627
private const string ConditionalFeature = "ConditionalFeature";
2728
private const string ContextualFeature = "ContextualFeature";
29+
private const string MissingFeature = "MissingFeature";
2830

2931
[Fact]
3032
public async Task ReadsConfiguration()
@@ -33,6 +35,12 @@ public async Task ReadsConfiguration()
3335

3436
var services = new ServiceCollection();
3537

38+
services
39+
.Configure<FeatureManagementOptions>(options =>
40+
{
41+
options.IgnoreMissingFeatures = true;
42+
});
43+
3644
services
3745
.AddSingleton(config)
3846
.AddFeatureManagement()
@@ -483,5 +491,59 @@ public async Task SwallowsExceptionForMissingFeatureFilter()
483491

484492
Assert.False(isEnabled);
485493
}
494+
495+
[Fact]
496+
public async Task ThrowsOnMissingFeature()
497+
{
498+
IConfiguration config = new ConfigurationBuilder().AddJsonFile("appsettings.json").Build();
499+
500+
var services = new ServiceCollection();
501+
502+
services
503+
.Configure<FeatureManagementOptions>(options =>
504+
{
505+
options.IgnoreMissingFeatures = false;
506+
});
507+
508+
services
509+
.AddSingleton(config)
510+
.AddFeatureManagement()
511+
.AddFeatureFilter<TestFilter>();
512+
513+
ServiceProvider serviceProvider = services.BuildServiceProvider();
514+
515+
IFeatureManager featureManager = serviceProvider.GetRequiredService<IFeatureManager>();
516+
517+
FeatureManagementException e = await Assert.ThrowsAsync<FeatureManagementException>(async () => await featureManager.IsEnabledAsync(MissingFeature));
518+
519+
Assert.Equal(FeatureManagementError.MissingFeature, e.Error);
520+
}
521+
522+
[Fact]
523+
public async Task SwallowsOnMissingFeature()
524+
{
525+
IConfiguration config = new ConfigurationBuilder().AddJsonFile("appsettings.json").Build();
526+
527+
var services = new ServiceCollection();
528+
529+
services
530+
.Configure<FeatureManagementOptions>(options =>
531+
{
532+
options.IgnoreMissingFeatures = true;
533+
});
534+
535+
services
536+
.AddSingleton(config)
537+
.AddFeatureManagement()
538+
.AddFeatureFilter<TestFilter>();
539+
540+
ServiceProvider serviceProvider = services.BuildServiceProvider();
541+
542+
IFeatureManager featureManager = serviceProvider.GetRequiredService<IFeatureManager>();
543+
544+
var isEnabled = await featureManager.IsEnabledAsync(ConditionalFeature);
545+
546+
Assert.False(isEnabled);
547+
}
486548
}
487549
}

0 commit comments

Comments
 (0)