| name | feature-flags |
| description | Feature flag evaluation backed by Unleash using AT.Common.FeatureFlags. Use this skill when adding, checking, or testing feature flags in a .NET application, exposing a feature flag HTTP endpoint, or configuring context-based flag evaluation. |
| license | MIT |
| metadata | {"domain":"backend","tags":"feature-flags unleash dotnet toggles context testing"} |
FeatureFlags Skill — Arbeidstilsynet/dotnet-common
Arbeidstilsynet.Common.FeatureFlags (AT.Common.FeatureFlags.Publish) wraps the Unleash client in a simple IFeatureFlags interface with context support, automatic fallback for testing, and an optional HTTP endpoint.
Installation
dotnet add package Arbeidstilsynet.Common.FeatureFlags
Configuration
Add to appsettings.json:
{
"FeatureFlags": {
"Url": "https://unleash.example.com/api",
"ApiKey": "your-api-key-here",
"AppName": "my-application",
"Environment": "development"
}
}
Dependency Injection Setup
using Arbeidstilsynet.Common.FeatureFlags.DependencyInjection;
using Arbeidstilsynet.Common.FeatureFlags.Model;
var featureFlagSettings = builder.Configuration
.GetSection("FeatureFlags")
.Get<FeatureFlagSettings>() ?? new FeatureFlagSettings();
builder.Services.AddFeatureFlags(featureFlagSettings);
Note: If Url or ApiKey is empty in featureFlagSettings, the service automatically uses FakeUnleash — all flags are disabled by default. This keeps tests and local development working without an Unleash server.
Checking Feature Flags
Inject IFeatureFlags into any service or controller.
using Arbeidstilsynet.Common.FeatureFlags.Ports;
public class MyService(IFeatureFlags featureFlags)
{
public void DoSomething()
{
if (featureFlags.IsEnabled("my-new-feature"))
{
}
else
{
}
}
}
Context-based evaluation
Pass a FeatureFlagContext to enable user-specific or group-specific rollouts:
var context = new FeatureFlagContext
{
UserId = userId,
AppName = appName,
SessionId = sessionId,
};
if (featureFlags.IsEnabled("user-specific-feature", context))
{
}
HTTP Endpoint
Expose a feature flag check endpoint for frontend or cross-service consumers:
app.MapFeatureFlagEndpoint();
app.MapFeatureFlagEndpoint("/api/features");
FeatureFlagRequest
public record FeatureFlagRequest
{
public required string FeatureName { get; init; }
public FeatureFlagContext? Context { get; init; }
}
FeatureFlagResponse
public record FeatureFlagResponse
{
public required bool IsEnabled { get; init; }
public required string FeatureName { get; init; }
}
Request:
POST /featureflag
Content-Type: application/json
{
"featureName": "my-new-feature",
"context": {
"userId": "user123",
"appName": "my-application",
"sessionId": "abc-123"
}
}
Response:
{
"featureName": "my-new-feature",
"isEnabled": true
}
Testing
When Url or ApiKey is empty, FakeUnleash is registered automatically. Toggle flags directly via the FakeUnleash instance in tests:
services.AddFeatureFlags(new FeatureFlagSettings());
var fakeUnleash = (FakeUnleash)serviceProvider.GetRequiredService<IUnleash>();
fakeUnleash.SetToggle("test-feature", true);
Or rely on the auto-fallback (all flags disabled by default):
services.AddFeatureFlags(new FeatureFlagSettings());
IFeatureFlags Interface
public interface IFeatureFlags
{
bool IsEnabled(string featureName, FeatureFlagContext? context = null);
}
Adding a Feature Flag — Checklist
- Define the flag in Unleash (name must match the string passed to
IsEnabled)
- Wrap the new code path with
if (featureFlags.IsEnabled("flag-name"))
- In tests, use
fakeUnleash.SetToggle("flag-name", true) to activate the flag
- Remove the flag and old code path once the feature is fully rolled out