This product is not supported for your selected
Datadog site . (
).
概要 このページでは、Datadog Feature Flags SDK を使用して .NET アプリケーションをインスツルメントする方法について説明します。.NET SDK は、Feature Flags 管理のオープン標準である OpenFeature と統合され、Datadog .NET トレーサー (dd-trace-dotnet) の Remote Configuration を通じてフラグ更新を受信します。
このガイドでは、SDK のインストールと有効化、OpenFeature クライアントの作成、およびアプリケーションでの Feature Flags の評価方法について説明します。
前提条件 .NET Feature Flags SDK をセットアップする前に、以下の条件を満たしていることを確認してください。
Datadog Agent バージョン 7.55 以降 (Remote Configuration が有効)Datadog API キー が Agent で構成済みDatadog .NET SDK (dd-trace-dotnet):.NET 6 以降の場合はバージョン 3.36.0 以降 .NET Framework 4.6.2 以降の場合はバージョン 3.38.0 以降 以下の環境変数を設定します。
Copy
# Required: Enable the feature flags provider
DD_EXPERIMENTAL_FLAGGING_PROVIDER_ENABLED = true
# Optional: Enable flag evaluation metrics
DD_METRICS_OTEL_ENABLED = true
# Required: Service identification
DD_SERVICE = <YOUR_SERVICE_NAME>
DD_ENV = <YOUR_ENVIRONMENT>EXPERIMENTAL_ プレフィックスは後方互換性のために保持されていますが、プロバイダー自体は安定しています。
必要なトレーサーのバージョンや Agent OTLP のセットアップを含む feature_flag.evaluations の構成については、サーバーサイドの Feature Flag 評価メトリクスをセットアップする を参照してください。利用可能なグラフ作成の詳細については、Feature Flag グラフ を参照してください。
インストール NuGet を使用して Datadog .NET SDK および OpenFeature SDK をインストールします。
Copy
dotnet add package Datadog.FeatureFlags.OpenFeature
dotnet add package OpenFeature または、それらを .csproj ファイルに追加します。
Copy
<ItemGroup>
<PackageReference Include= "Datadog.FeatureFlags.OpenFeature" />
<PackageReference Include= "OpenFeature" />
</ItemGroup> フラグ評価メトリクスを有効にする場合は、OpenTelemetry SDK と OTLP エクスポーターもインストールする必要があります。
Copy
dotnet add package OpenTelemetry
dotnet add package OpenTelemetry.Exporter.OpenTelemetryProtocol または、それらを .csproj ファイルに追加します。
Copy
<ItemGroup>
<PackageReference Include= "OpenTelemetry" />
<PackageReference Include= "OpenTelemetry.Exporter.OpenTelemetryProtocol" />
</ItemGroup> SDK の初期化 Datadog OpenFeature プロバイダーを OpenFeature API に登録します。このプロバイダーは、Datadog .NET トレーサーの Remote Configuration システムに接続して、フラグ構成を受信します。
ブロッキングの初期化 SetProviderAsync を await と共に使用して、初期フラグ構成が受信されるまで評価をブロックします。これにより、アプリケーションがリクエストの処理を開始する前にフラグの準備が整います。
Copy
using OpenFeature ;
using Datadog.FeatureFlags.OpenFeature ;
// Create and register the Datadog provider
var provider = new DatadogProvider ();
await Api . Instance . SetProviderAsync ( provider );
// Create an OpenFeature client
var client = Api . Instance . GetClient ( "my-service" );
// Your application code here 非ブロッキングの初期化 SetProvider を使用して、待機せずにプロバイダーを登録します。構成が受信されるまで、フラグ評価はデフォルト値を返します。
Copy
using OpenFeature ;
using Datadog.FeatureFlags.OpenFeature ;
// Create and register the Datadog provider
var provider = new DatadogProvider ();
Api . Instance . SetProvider ( provider );
// Create an OpenFeature client
var client = Api . Instance . GetClient ( "my-service" );
// Your application code here
// Flag evaluations return defaults until configuration is received クライアントを作成する フラグを評価するために OpenFeature クライアントを作成します。アプリケーションの異なる部分に対して、異なる名前を持つ複数のクライアントを作成できます。
Copy
// Create a client for your application
var client = Api . Instance . GetClient ( "my-service" ); 評価コンテキストを設定する フラグのターゲティング対象となるユーザーまたはエンティティを識別する評価コンテキストを定義します。評価コンテキストには、どのフラグバリエーションを返すかを決定するために使用される属性が含まれます。
Datadog Feature Flags では、評価コンテキスト属性が文字列、数値、ブール値といったフラットなプリミティブ値でなければなりません。ネストされたオブジェクトや配列は渡さないでください。これらはサポートされておらず、エクスポージャーデータが破棄される原因となる可能性があります。
Copy
using OpenFeature.Model ;
var evalCtx = 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 (); 注: サーバーサイドアプリケーションでは、現在のユーザーに基づいてリクエストごとに評価コンテキストを一度構築し、そのリクエスト内のすべてのフラグ評価に同じコンテキストを渡してください。ユーザー属性が変更された場合にのみ、コンテキストを再構築してください。
ターゲティングキーは、一貫したトラフィックディストリビューション (パーセンテージロールアウト) に使用されます。追加の属性により、上記の例で「米国のユーザーに対して有効にする」や「プレミアム層のユーザーに対して有効にする」といったターゲティングルールが可能になります。
フラグを評価する プロバイダーを設定し、クライアントを作成した後、アプリケーション全体でフラグを評価できます。フラグの評価はローカルで高速に行われます。SDK はローカルにキャッシュされた構成データを使用するため、評価中にネットワークリクエストは発生しません。
各フラグはキー (一意の文字列) によって識別され、想定されるタイプの値を返すタイプ指定されたメソッドで評価できます。フラグが存在しない場合や評価できない場合、SDK は提供されたデフォルト値を返します。
ブールフラグ オン/オフや真/偽の条件を表すフラグには、GetBooleanValueAsync を使用します。
Copy
var enabled = await client . GetBooleanValueAsync ( "new-checkout-flow" , false , evalCtx );
if ( enabled )
{
ShowNewCheckout ();
}
else
{
ShowLegacyCheckout ();
} 文字列フラグ 複数のバリアントや構成文字列を選択するフラグには、GetStringValueAsync を使用します。
Copy
var theme = await client . GetStringValueAsync ( "ui-theme" , "light" , evalCtx );
switch ( theme )
{
case "dark" :
SetDarkTheme ();
break ;
case "light" :
SetLightTheme ();
break ;
default :
SetLightTheme ();
break ;
} 数値フラグ 数値フラグの場合、GetIntegerValueAsync または GetDoubleValueAsync を使用します。これらは、機能が制限、パーセンテージ、乗数などの数値パラメーターに依存する場合に適しています。
Copy
var maxItems = await client . GetIntegerValueAsync ( "cart-max-items" , 20 , evalCtx );
var discountRate = await client . GetDoubleValueAsync ( "discount-rate" , 0.0 , evalCtx ); オブジェクトフラグ 構造化データの場合、GetObjectValueAsync を使用します。これは、複雑な構成にアクセスするために使用できる値を返します。
Copy
using OpenFeature.Model ;
var defaultConfig = new Value ( new Structure ( new Dictionary < string , Value >
{
["maxRetries"] = new Value ( 3 ),
["timeout"] = new Value ( 30 )
}));
var config = await client . GetObjectValueAsync ( "feature-config" , defaultConfig , evalCtx );
// Access configuration values
var maxRetries = config . AsStructure ?[ "maxRetries" ]. AsInteger ?? 3 ;
var timeout = config . AsStructure ?[ "timeout" ]. AsInteger ?? 30 ; フラグ評価の詳細 フラグの値だけでなく詳細情報が必要な場合は、*DetailsAsync メソッドを使用します。これらは、評価された値とその評価を説明するメタデータの両方を返します。
Copy
var details = await client . GetBooleanDetailsAsync ( "new-feature" , false , evalCtx );
Console . WriteLine ( $"Value: {details.Value}" );
Console . WriteLine ( $"Variant: {details.Variant}" );
Console . WriteLine ( $"Reason: {details.Reason}" );
Console . WriteLine ( $"Error Type: {details.ErrorType}" );
Console . WriteLine ( $"Error Message: {details.ErrorMessage}" ); フラグの詳細は、評価の動作をデバッグし、ユーザーが特定の値を受け取った理由を理解する上で役立ちます。
プロバイダーの初期化の待機 デフォルトでは、最初の Remote Configuration ペイロードが受信されるまで、プロバイダーは非同期に初期化されてフラグ評価はデフォルト値を返します。アプリケーションでリクエストを処理する前にフラグの準備が必要な場合は、イベントハンドラーを使用してプロバイダーの初期化を待機できます。
Copy
using OpenFeature ;
using OpenFeature.Constant ;
var taskCompletionSource = new TaskCompletionSource < bool >();
// Register event handler
Api . 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 provider
var provider = new DatadogProvider ();
Api . Instance . SetProvider ( provider );
// Wait for provider to be ready (with timeout)
var timeout = Task . Delay ( TimeSpan . FromSeconds ( 30 ));
var completedTask = await Task . WhenAny ( taskCompletionSource . Task , timeout );
if ( completedTask == timeout )
{
Console . WriteLine ( "Provider initialization timed out" );
}
// Create client and evaluate flags
var client = Api . Instance . GetClient (); クリーンアップ アプリケーションを終了する際は、OpenFeature API をシャットダウンしてリソースをクリーンアップしてください。
Copy
await Api . Instance . ShutdownAsync (); テスト 実際の DatadogProvider を使用して専用の Datadog テスト環境に対してテストを行うか、OpenFeature の InMemoryProvider に置き換えてテストコード内でフラグ値を直接制御することができます。このセクションでは、テストを外部から隔離し、オフライン環境でも実行可能なインメモリ方式について説明します。InMemoryProvider は OpenFeature NuGet パッケージ (ネームスペースOpenFeature.Providers.Memory) に含まれているため、本番環境用にインストール済みのもの以外に追加の依存関係は必要ありません。
Api.Instanceはシングルトンです。xUnit の IAsyncLifetime を使用してテストごとにプロバイダーを設定し、DisposeAsync で破棄することでテストの順序に依存する問題を回避できます。セットアップを共有するより高速なスイートの場合は、InMemoryProvider.UpdateFlagsAsync(...) を使用してプロバイダーを再登録することなくテスト間でフラグの状態を変更します。
Copy
using OpenFeature ;
using OpenFeature.Model ;
using OpenFeature.Providers.Memory ;
using Xunit ;
public class CheckoutFlagTests : IAsyncLifetime
{
private FeatureClient _client = null !;
public async Task InitializeAsync ()
{
var flags = new Dictionary < string , Flag >
{
["new-checkout-flow"] = new Flag < bool >(
variants : new Dictionary < string , bool > { [ "on" ] = true , [ "off" ] = false },
defaultVariant : "on" ),
["ui-theme"] = new Flag < string >(
variants : new Dictionary < string , string > { [ "dark" ] = "dark" , [ "light" ] = "light" },
defaultVariant : "light" ,
contextEvaluator : ctx =>
ctx . GetValue ( "tier" )?. AsString == "premium" ? "dark" : "light" ),
};
await Api . Instance . SetProviderAsync ( new InMemoryProvider ( flags ));
_client = Api . Instance . GetClient ( "test" );
}
public Task DisposeAsync () => Api . Instance . ShutdownAsync ();
[Fact]
public async Task NewCheckoutEnabledByDefault ()
{
Assert . True ( await _client . GetBooleanValueAsync ( "new-checkout-flow" , false ));
}
[Fact]
public async Task PremiumUserGetsDarkTheme ()
{
var ctx = EvaluationContext . Builder ()
. SetTargetingKey ( "u1" )
. Set ( "tier" , "premium" )
. Build ();
Assert . Equal ( "dark" , await _client . GetStringValueAsync ( "ui-theme" , "light" , ctx ));
}
} 同じパターンが NUnit ([SetUp]/[TearDown]) および MSTest ([TestInitialize]/[TestCleanup]) に適用されます。ASP.NET Core のインテグレーションテストでは、アプリケーションの起動前に WebApplicationFactory.ConfigureTestServices 内で InMemoryProvider を登録してください。
テストを SDK の内部構造に結合させないようにするため、Moq などのライブラリで Datadog プロバイダーをモックするよりも InMemoryProvider に置き換えることを推奨します。
トラブルシューティング プロバイダーが有効になっていない プロバイダーが有効になっていないという警告が表示される場合は、ご利用の環境またはアプリケーション構成で DD_EXPERIMENTAL_FLAGGING_PROVIDER_ENABLED=true が設定されていることを確認してください。
Copy
DD_EXPERIMENTAL_FLAGGING_PROVIDER_ENABLED = trueコンテナ化されたアプリケーションの場合は、これを Docker または Kubernetes の構成に追加してください。
Copy
environment :
- DD_EXPERIMENTAL_FLAGGING_PROVIDER_ENABLED=true
- DD_SERVICE=my-service
- DD_ENV=production Remote Configuration が機能していない Remote Configuration が機能していることを確認するために、以下を確認してください。
Datadog Agent が 必要なバージョン Agent で Remote Configuration が有効になっている DD_SERVICE および DD_ENV 環境変数が設定されているSDK が Agent と通信できる 非同期評価エラー .NET OpenFeature SDK は、すべてのフラグ評価に非同期メソッドを使用します。await を使用しているか、返された Task を適切に処理していることを確認してください。
Copy
// Correct: Using await
var enabled = await client . GetBooleanValueAsync ( "flag-key" , false , context );
// Incorrect: Not awaiting (will not work as expected)
var enabled = client . GetBooleanValueAsync ( "flag-key" , false , context ); 参考資料