Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -167,10 +167,22 @@ We support
}
}

bool evaluate = true;

val = configurationSection[nameof(FeatureDefinition.Evaluate)];

if (!string.IsNullOrEmpty(val) && !bool.TryParse(val, out evaluate))
{
throw new FeatureManagementException(
FeatureManagementError.InvalidConfiguration,
$"The feature '{configurationSection.Key}' has an invalid value for the '{nameof(FeatureDefinition.Evaluate)}' property.");
}

return new FeatureDefinition()
{
Name = configurationSection.Key,
EnabledFor = enabledFor
EnabledFor = enabledFor,
Evaluate = evaluate
};
}

Expand Down
6 changes: 6 additions & 0 deletions src/Microsoft.FeatureManagement/FeatureDefinition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,11 @@ public class FeatureDefinition
/// The feature filters that the feature can be enabled for.
/// </summary>
public IEnumerable<FeatureFilterConfiguration> EnabledFor { get; set; } = new List<FeatureFilterConfiguration>();

/// <summary>
/// Dictates whether the feature should be evaluated. If false, the feature will be considered disabled.
/// The default value is true.
/// </summary>
public bool Evaluate { get; set; } = true;
}
}
7 changes: 6 additions & 1 deletion src/Microsoft.FeatureManagement/FeatureManagementError.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ public enum FeatureManagementError
/// <summary>
/// A feature that was requested for evaluation was not found.
/// </summary>
MissingFeature
MissingFeature,

/// <summary>
/// An invalid configuration was encountered when performing a feature management operation.
/// </summary>
InvalidConfiguration
}
}
5 changes: 3 additions & 2 deletions src/Microsoft.FeatureManagement/FeatureManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@ private async Task<bool> IsEnabledAsync<TContext>(string feature, TContext appCo

FeatureDefinition featureDefinition = await _featureDefinitionProvider.GetFeatureDefinitionAsync(feature).ConfigureAwait(false);

if (featureDefinition != null)
if (featureDefinition != null
&& featureDefinition.Evaluate)
{
//
// Check if feature is always on
Expand Down Expand Up @@ -141,7 +142,7 @@ private async Task<bool> IsEnabledAsync<TContext>(string feature, TContext appCo
}
}
}
else
else if (featureDefinition == null)
{
string errorMessage = $"The feature declaration for the feature '{feature}' was not found.";

Expand Down
22 changes: 22 additions & 0 deletions tests/Tests.FeatureManagement/FeatureManagement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ public class FeatureManagement
private const string OffFeature = "OffFeature";
private const string ConditionalFeature = "ConditionalFeature";
private const string ContextualFeature = "ContextualFeature";
private const string AlwaysOnFeature = "AlwaysOnFeature";
private const string NonEvaluatedAlwaysOnFeature = "NonEvaluatedAlwaysOnFeature";

[Fact]
public async Task ReadsConfiguration()
Expand Down Expand Up @@ -615,6 +617,26 @@ public async Task ThreadsafeSnapshot()
}
}

[Fact]
public async Task TogglesEvaluation()
{
IConfiguration config = new ConfigurationBuilder().AddJsonFile("appsettings.json").Build();

var services = new ServiceCollection();

services
.AddSingleton(config)
.AddFeatureManagement();

ServiceProvider serviceProvider = services.BuildServiceProvider();

IFeatureManager featureManager = serviceProvider.GetRequiredService<IFeatureManager>();

Assert.True(await featureManager.IsEnabledAsync(AlwaysOnFeature));

Assert.False(await featureManager.IsEnabledAsync(NonEvaluatedAlwaysOnFeature));
}

private static void DisableEndpointRouting(MvcOptions options)
{
#if NET5_0 || NETCOREAPP3_1
Expand Down
15 changes: 15 additions & 0 deletions tests/Tests.FeatureManagement/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,21 @@
}
}
]
},
"AlwaysOnFeature": {
"EnabledFor": [
{
"Name": "AlwaysOn"
}
]
},
"NonEvaluatedAlwaysOnFeature": {
"Evaluate": false,
"EnabledFor": [
{
"Name": "AlwaysOn"
}
]
}
}
}