LaunchDarkly Labs
This repository is maintained by LaunchDarkly Labs. While we try to keep it up to date, it is not officially supported by LaunchDarkly. For officially supported SDKs and tools, visit launchdarkly.com.
A small ASP.NET Core sample that evaluates a boolean flag using a multi-context with user and request kinds, the LaunchDarkly server-side .NET SDK, and the LaunchDarkly Observability plugin (OpenTelemetry + flag evaluation hooks). It includes a web UI with a form, burst simulation for OTel-style traces, and indented JSON results (System.Text.Json with WriteIndented). Use it to learn multi-context evaluation and observability wiring; copy patterns into your own services via docs/IMPLEMENTING_MULTI_CONTEXT.md.
- .NET 9 SDK (or retarget the project to
net8.0if you prefer) - A LaunchDarkly server-side SDK key for your environment
-
Clone this repository.
-
Restore packages:
dotnet restore LaunchDarklySample/LaunchDarklySample.csproj
-
Configure your SDK key (see Configuration: user secrets below)—do not commit secrets.
cd LaunchDarklySample
dotnet user-secrets set "LaunchDarkly:SdkKey" "YOUR_SERVER_SIDE_SDK_KEY"
dotnet runOpen the URL shown in the console (often http://localhost:5268), set a flag key that exists in your project, and click Evaluate flag.
- Feature flag evaluation — Choose a boolean flag key, edit user and request (simulated) attributes, then evaluate. See Run for the full UI walkthrough.
- Burst simulation — Run multiple evaluations for the same user with delays to generate separate OpenTelemetry activities.
- Implementation guide — See
docs/IMPLEMENTING_MULTI_CONTEXT.mdto port multi-context patterns to other .NET apps.
Do this once per environment you use with this sample.
- In LaunchDarkly, open your project → Contexts (or Account settings → Contexts, depending on your UI).
- Ensure you have context kinds named
userandrequest.- If your project already has
user, you only need to addrequest. - If you create new kinds, use the exact names
userandrequestso they match the code (defaultuser kind +ContextKind.Of("request")).
- If your project already has
You will use these kinds when building targeting rules or experiments.
- Go to Feature flags → Create flag.
- Choose Boolean (on/off).
- Set the flag key to match this app’s config, e.g.
sample-boolean-flag(or any key you prefer — then setLaunchDarkly:FlagKeyto match). - Save the flag.
- Open the flag → Targeting (or Rules).
- Add rules that use context attributes for
user(e.g. key,tier,country) and/orrequest(e.g.region,clientIp,sessionId). - The sample sends attributes such as:
- User:
userkey,name,email,country,tier - Request:
method,path,clientIp,userAgent,region,sessionId,edgePop,simulated
- User:
You can start with 100% on or off to validate wiring, then add rules.
The app reads LaunchDarkly:FlagKey (default sample-boolean-flag). If your flag key differs, set:
dotnet user-secrets set "LaunchDarkly:FlagKey" "your-flag-key"This project reads settings under the LaunchDarkly section (see appsettings.json). Secrets (SDK key and anything you treat as sensitive) should live in the .NET User Secrets store so they are not committed to git.
The sample project already has a <UserSecretsId> in LaunchDarklySample.csproj, so you do not need dotnet user-secrets init unless you created a new project from scratch.
User secrets are tied to the project (the .csproj), not the solution file.
cd path/to/ld-dotnet-samplemulticontext/LaunchDarklySampleFrom the repo root you can also pass the project explicitly:
dotnet user-secrets --project LaunchDarklySample/LaunchDarklySample.csproj listOnly if your .csproj does not contain <UserSecretsId>...</UserSecretsId>:
dotnet user-secrets initThat adds a random UserSecretsId to the project file. This repo already includes one, so you can skip this step.
Run these from LaunchDarklySample/ (or add --project ... to each command). Replace the placeholder values with yours.
Required — server-side SDK key (from LaunchDarkly: Project settings → Environments → your environment → SDK key):
dotnet user-secrets set "LaunchDarkly:SdkKey" "sdk-xxxxxxxx-YourRealSdkKey"Optional — flag key (must match the boolean flag’s key in LaunchDarkly; defaults to sample-boolean-flag in appsettings.json if unset):
dotnet user-secrets set "LaunchDarkly:FlagKey" "sample-boolean-flag"Optional — observability service identity (shown in LaunchDarkly Observability for this app’s telemetry):
dotnet user-secrets set "LaunchDarkly:ServiceName" "ld-dotnet-sample-multicontext"
dotnet user-secrets set "LaunchDarkly:ServiceVersion" "1.0.0"You can set only what you need. Minimum to run is LaunchDarkly:SdkKey.
dotnet user-secrets listdotnet user-secrets list prints keys and values in plain text in your terminal (useful for debugging; avoid screen-sharing while it is visible). Example shape:
LaunchDarkly:SdkKey = sdk-abc123...
LaunchDarkly:FlagKey = sample-boolean-flag
LaunchDarkly:ServiceName = ld-dotnet-sample-multicontext
LaunchDarkly:ServiceVersion = 1.0.0
dotnet user-secrets remove "LaunchDarkly:FlagKey"
dotnet user-secrets set "LaunchDarkly:FlagKey" "new-flag-key"Clear all secrets for this project id:
dotnet user-secrets clearUser secrets are outside the repository. Typical locations:
| OS | Path pattern |
|---|---|
| macOS / Linux | ~/.microsoft/usersecrets/<UserSecretsId>/secrets.json |
| Windows | %APPDATA%\Microsoft\UserSecrets\<UserSecretsId>\secrets.json |
The <UserSecretsId> is the GUID in LaunchDarklySample.csproj. Editing secrets.json by hand works, but dotnet user-secrets is safer.
Anything under LaunchDarkly in configuration can be set with the double-underscore convention (useful in Docker, CI, or shell exports):
| Configuration key | Environment variable |
|---|---|
LaunchDarkly:SdkKey |
LaunchDarkly__SdkKey |
LaunchDarkly:FlagKey |
LaunchDarkly__FlagKey |
LaunchDarkly:ServiceName |
LaunchDarkly__ServiceName |
LaunchDarkly:ServiceVersion |
LaunchDarkly__ServiceVersion |
Example (one line in zsh/bash):
export LaunchDarkly__SdkKey="sdk-xxxxx"
export LaunchDarkly__FlagKey="sample-boolean-flag"
dotnet run --project LaunchDarklySamplePrecedence (highest wins): environment variables → user secrets → appsettings.{Environment}.json → appsettings.json.
LaunchDarklySample/appsettings.json keeps non-secret defaults (e.g. FlagKey, ServiceName) and leaves SdkKey empty. Put real keys in user secrets or environment variables, not in committed JSON.
dotnet run --project LaunchDarklySampleOpen the root URL from LaunchDarklySample/Properties/launchSettings.json (often http://localhost:5268).
- Set Flag key to the boolean flag you want to evaluate (defaults to
LaunchDarkly:FlagKeyfrom config, orsample-boolean-flagif unset). Leave blank to use that default. - Fill in User context (key, name, email, country, tier).
- Adjust Simulated request context (fake client IP, User-Agent, region, session, edge POP, etc.) — these are not your real browser IP; they stand in for gateway-style data on the
requestcontext. - Optionally set Burst simulation: Number of simulated requests (1–100) and Delay between requests (ms) (0–60,000). The same user and same session are reused; each iteration gets a new
requestkey (sim-{batchId}-{index}) and a childActivity(SimulatedRequest) under the HTTP request so OpenTelemetry / LaunchDarkly can show separate spans. Delays spread evaluations over time for metrics and charts. - Click Evaluate flag to see pretty-printed JSON including
iterations,simulationBatchId, and timings.
When burst > 1, the optional Request key field is ignored (each iteration assigns its own key).
If the port is busy, run on another URL:
dotnet run --project LaunchDarklySample --urls "http://localhost:5288"LdClientconfigured withObservabilityPlugin(OTLP and ASP.NET Core instrumentation via the plugin’s dependencies).TracingHookso flag evaluations attach compatible data to the active diagnostic activity (aligned with LaunchDarkly’s OpenTelemetry guidance for server-side .NET).Context.MultiBuilder()combining a user context (with optional attributes) and arequestcontext (with simulated request metadata) forBoolVariationDetail.- HTML UI with a dark theme and indented JSON output for quick inspection.
- Burst simulation — repeated evaluations for one user with configurable delay, distinct request contexts, and per-iteration activities for OTel metrics/traces.
- Implementing multi-context in another .NET app — concepts (context, kind, multi-context), step-by-step snippets for
LdClient,Context.MultiBuilder, evaluation, optional observability hooks, and pitfalls.
LaunchDarklySample/Program.cs— web UI, SDK + observability setup, multi-context evaluationdocs/IMPLEMENTING_MULTI_CONTEXT.md— portable implementation guide with code snippetsLaunchDarklySample.sln— solution fileCHANGELOG.md— version history (Keep a Changelog)
Apache License 2.0 — see the LICENSE file.
See CHANGELOG.md.