This page describes how to instrument your .NET application with the Datadog Feature Flags SDK. The .NET SDK integrates with OpenFeature, an open standard for feature flag management, and uses the Datadog tracer’s Remote Configuration to receive flag updates in real time.
This guide explains how to install and enable the SDK, create an OpenFeature client, and evaluate feature flags in your application.
Prerequisites
Before setting up the .NET Feature Flags SDK, ensure you have:
Register the Datadog OpenFeature provider with the OpenFeature API. The provider connects to the Datadog tracer’s Remote Configuration system to receive flag configurations.
Blocking initialization
Use SetProviderAsync with await to block evaluation until the initial flag configuration is received. This ensures flags are ready before your application starts handling requests.
usingOpenFeature;usingDatadog.Trace.FeatureFlags.OpenFeature;// Create and register the Datadog providervarprovider=newDatadogProvider();awaitApi.Instance.SetProviderAsync(provider);// Create an OpenFeature clientvarclient=Api.Instance.GetClient("my-service");// Your application code here
Non-blocking initialization
Use SetProvider to register the provider without waiting. Flag evaluations return default values until the configuration is received.
usingOpenFeature;usingDatadog.Trace.FeatureFlags.OpenFeature;// Create and register the Datadog providervarprovider=newDatadogProvider();Api.Instance.SetProvider(provider);// Create an OpenFeature clientvarclient=Api.Instance.GetClient("my-service");// Your application code here// Flag evaluations return defaults until configuration is received
Create a client
Create an OpenFeature client to evaluate flags. You can create multiple clients with different names for different parts of your application:
// Create a client for your applicationvarclient=Api.Instance.GetClient("my-service");
Set the evaluation context
Define an evaluation context that identifies the user or entity for flag targeting. The evaluation context includes attributes used to determine which flag variations should be returned:
usingOpenFeature.Model;varevalCtx=EvaluationContext.Builder().SetTargetingKey("user-123")// Targeting key (typically user ID).Set("email","user@example.com").Set("country","US").Set("tier","premium").Set("age",25).Build();
Note: In server-side applications, build the evaluation context once per request based on the current user, then pass the same context to all flag evaluations within that request. Only rebuild the context if user attributes change.
The targeting key is used for consistent traffic distribution (percentage rollouts). Additional attributes enable targeting rules, such as “enable for users in the US” or “enable for premium tier users” in the example above.
Evaluate flags
After setting up the provider and creating a client, you can evaluate flags throughout your application. Flag evaluation is local and fast—the SDK uses locally cached configuration data, so no network requests occur during evaluation.
Each flag is identified by a key (a unique string) and can be evaluated with a typed method that returns a value of the expected type. If the flag doesn’t exist or cannot be evaluated, the SDK returns the provided default value.
Boolean flags
Use GetBooleanValueAsync for flags that represent on/off or true/false conditions:
For numeric flags, use GetIntegerValueAsync or GetDoubleValueAsync. These are appropriate when a feature depends on a numeric parameter such as a limit, percentage, or multiplier:
When you need more than just the flag value, use the *DetailsAsync methods. These return both the evaluated value and metadata explaining the evaluation:
Flag details help you debug evaluation behavior and understand why a user received a given value.
Waiting for provider initialization
By default, the provider initializes asynchronously and flag evaluations return default values until the first Remote Configuration payload is received. If your application requires flags to be ready before handling requests, you can wait for the provider to initialize using event handlers:
usingOpenFeature;usingOpenFeature.Constant;vartaskCompletionSource=newTaskCompletionSource<bool>();// Register event handlerApi.Instance.AddHandler(ProviderEventTypes.ProviderReady,(eventDetails)=>{Console.WriteLine("Provider is ready");taskCompletionSource.SetResult(true);});Api.Instance.AddHandler(ProviderEventTypes.ProviderError,(eventDetails)=>{Console.WriteLine($"Provider error: {eventDetails.Message}");taskCompletionSource.SetResult(false);});// Set providervarprovider=newDatadogProvider();Api.Instance.SetProvider(provider);// Wait for provider to be ready (with timeout)vartimeout=Task.Delay(TimeSpan.FromSeconds(30));varcompletedTask=awaitTask.WhenAny(taskCompletionSource.Task,timeout);if(completedTask==timeout){Console.WriteLine("Provider initialization timed out");}// Create client and evaluate flagsvarclient=Api.Instance.GetClient();
Cleanup
When your application exits, shut down the OpenFeature API to clean up resources:
awaitApi.Instance.ShutdownAsync();
Troubleshooting
Provider not enabled
If you receive warnings about the provider not being enabled, ensure DD_EXPERIMENTAL_FLAGGING_PROVIDER_ENABLED=true is set in your environment or application configuration:
DD_EXPERIMENTAL_FLAGGING_PROVIDER_ENABLED=true
For containerized applications, add this to your Docker or Kubernetes configuration:
DD_SERVICE and DD_ENV environment variables are set
The tracer can communicate with the Agent
Async evaluation errors
The .NET OpenFeature SDK uses async methods for all flag evaluations. Ensure you’re using await or properly handling the returned Task:
// Correct: Using awaitvarenabled=awaitclient.GetBooleanValueAsync("flag-key",false,context);// Incorrect: Not awaiting (will not work as expected)varenabled=client.GetBooleanValueAsync("flag-key",false,context);
Further reading
Additional helpful documentation, links, and articles: