Skip to main content

Advanced Usage

Learn advanced patterns for using feature flags in .NET applications.

Custom Context​

In console applications there is no ambient context such as HttpContext that feature filters can acquire and utilize to check if a feature should be on or off. In this case, applications need to provide an object representing a context into the feature management system for use by feature filters. This is done by using IFeatureManager.IsEnabledAsync<TContext>(string featureName, TContext appContext). The appContext object that is provided to the feature manager can be used by feature filters to evaluate the state of a feature.

MyAppContext context = new MyAppContext
{
AccountId = current.Id
};

if (await featureManager.IsEnabledAsync(feature, context))
{
...
}

IFeatureManagerSnapshot​

The IFeatureManagerSnapshot service can be injected anywhere else more suitable helper methods aren't available.

private readonly IFeatureManagerSnapshot _featureManager;

public UsersController(IFeatureManagerSnapshot featureManager)
{
_featureManager = featureManager;
}

[Route("")]
public async Task<IActionResult> Index()
{
var feature1Enabled = await _featureManager.IsEnabledAsync(FeatureFlags.Feature1);

return View(feature1Enabled ? "Feature1Index" : "Index");
}
info

IFeatureManagerSnapshot caches the first Boolean result for each feature during the request. Use it for repeated checks with the same user and context. Use IFeatureManager for distinct entity contexts, such as two Orders checked against the same flag.

IFeatureManager evaluates against the current cached definitions on each call. Evaluating another entity does not require another definitions request.

Serving Front-end Flags​

To ensure consistency between back-end and front-end decisions, the computed flags can be served to the user.

private readonly IFeatureManagerSnapshot _featureSnapshotManager;

public HomeController(IFeatureManagerSnapshot featureSnapshotManager)
{
_featureSnapshotManager = featureSnapshotManager;
}

[Route("flags.json")]
public async Task<IActionResult> FeatureFlags()
{
var model = new Dictionary<string, bool>();

await foreach (var name in _featureSnapshotManager.GetFeatureNamesAsync())
model.Add(name, await _featureSnapshotManager.IsEnabledAsync(name));

return Ok(model);
}

Working example​

Explore the .NET SDK Sample. Its guided sections include the first flag, request identity, Order VIP targeting, filter presets, named variants, Hangfire, health checks, and OpenAPI filtering. The README maps each section to its source files and includes a manual walkthrough.