次の方法で共有


.NET 機能の管理

Microsoft.FeatureManagement
Microsoft.FeatureManagement.AspNetCore
Microsoft.FeatureManagement.Telemetry.ApplicationInsights

.NET 機能管理ライブラリは、機能フラグに基づいてアプリケーション機能を開発および公開する方法を提供します。 新しい機能を開発する場合、多くのアプリケーションには、機能を有効にする必要がある場合やどのような条件で有効にするかなど、特別な要件があります。 このライブラリは、これらのリレーションシップを定義する方法を提供します。 また、一般的な .NET コード パターンと統合して、これらの機能を公開できるようにします。

機能フラグでは、.NET および ASP.NET Core アプリケーションで機能を動的にオンまたはオフにする方法が提供されます。 条件付きステートメントなどの基本的なユース ケースでは、機能フラグを使用できます。 ルートの条件付き追加やモデル ビュー コントローラー (MVC) フィルターなど、より高度なシナリオでも機能フラグを使用できます。 機能フラグは、.NET Core 構成システム上に構築されます。 任意の .NET Core 構成プロバイダーは、機能フラグのバックボーンとして機能させることができます。

.NET 機能管理ライブラリを使用する利点の一部を次に示します。

  • 機能管理には一般的な規則が使用されます。
  • これは、エントリへの障壁が低いです:
    • これは、 IConfiguration インターフェイス上に構築されています。
    • JSON ファイル機能フラグの設定をサポートしています。
  • 機能フラグの有効期間管理を提供します。
    • 構成値はリアルタイムで変更される可能性があります。
    • 機能フラグは、要求全体で一貫性を持つことができます。
  • 次の機能のサポートを提供することで、基本的なシナリオから複雑なシナリオまで説明します。
    • 宣言型構成ファイルを使用して機能のオンとオフを切り替える
    • さまざまなユーザーに異なるバリエーションの機能を表示する
    • サーバーへの呼び出しに基づいて機能の状態を動的に評価する
  • ASP.NET Core および MVC フレームワーク用の API 拡張機能を次の領域で提供します。
    • ルーティング
    • フィルター
    • アクション属性

.NET 機能管理ライブラリはオープン ソースです。 詳細については、 FeatureManagement-Dotnet GitHub リポジトリを参照してください。

機能フラグ

機能フラグは、有効または無効にできます。 フラグの状態は、機能フィルターを使用して条件付きにすることができます。

機能フィルター

機能フィルターは、機能を有効にする必要があるシナリオを定義します。 機能の状態を評価するために、いずれかのフィルターで機能が有効になっていると判断されるまで、その機能フィルターの一覧が走査されます。 この時点で、機能フィルターの走査は停止します。 どの機能フィルターも機能を有効にすることを示していない場合は、無効とみなされます。

たとえば、Microsoft Edge ブラウザー機能フィルターを設計するとします。 HTTP 要求が Microsoft Edge から送信された場合、機能フィルターによって、接続されている機能がアクティブ化されます。

機能フラグの構成

.NET Core 構成システムは、機能フラグの状態を決定するために使用されます。 このシステムの基盤は、 IConfiguration インターフェイスです。 IConfiguration の任意のプロバイダーは、機能フラグ ライブラリ用の機能状態プロバイダーとして使用できます。 このシステムは、 appsettings.json 構成ファイルから Azure App Configuration までのシナリオをサポートします。

機能フラグの宣言

機能管理ライブラリは、.NET Core IConfiguration システムのプロバイダーであるため、appsettings.json構成ファイルを機能フラグ ソースとしてサポートしています。 機能フラグは、 Microsoft Feature Management schemaを使用して宣言されます。 このスキーマは言語を選ばず、すべての Microsoft 機能管理ライブラリでサポートされています。

次の例のコードでは、JSON ファイルで機能フラグを宣言しています。

{
    "Logging": {
        "LogLevel": {
            "Default": "Warning"
        }
    },

    // Define feature flags in a JSON file.
    "feature_management": {
        "feature_flags": [
            {
                "id": "FeatureT",
                "enabled": false
            },
            {
                "id": "FeatureU",
                "enabled": true,
                "conditions": {}
            },
            {
                "id": "FeatureV",
                "enabled": true,
                "conditions": {
                    "client_filters": [
                        {  
                            "name": "Microsoft.TimeWindow",
                            "parameters": {
                                "Start": "Sun, 01 Jun 2025 13:59:59 GMT",
                                "End": "Fri, 01 Aug 2025 00:00:00 GMT"
                            }
                        }
                    ]
                }
            }
        ]
    }
}

JSON ドキュメントの feature_management セクションは、機能フラグの設定を読み込む規則によって使用されます。 このセクションでは、 feature_flags 配列のフィーチャー フラグ オブジェクトを一覧表示する必要があります。 このコードでは、3 つの機能フラグを一覧表示します。 各機能フラグ オブジェクトには、 idenabled プロパティがあります。

  • id値は、機能フラグを識別して参照するために使用する名前です。
  • enabled プロパティは、機能フラグの有効な状態を指定します。

enabledfalseされている場合、機能はオフになります。 enabledtrue場合、機能の状態はconditionsプロパティによって異なります。 conditions プロパティは、機能を動的に有効にするために使用される条件を宣言します。

  • 機能フラグに conditions プロパティがない場合、機能はオンになります。
  • 機能フラグに conditions プロパティがあり、その条件が満たされている場合、その機能はオンになります。
  • 機能フラグに conditions プロパティがあり、その条件が満たされていない場合、機能はオフになります。

特徴フィルターは、 client_filters 配列で定義されます。 前のコードでは、 FeatureV 機能フラグには、 Microsoft.TimeWindowという名前の機能フィルターがあります。 このフィルターは、構成可能な機能フィルターの例です。 このコードでは、このフィルターには parameters プロパティがあります。 このプロパティは、フィルターの構成に使用されます。 この場合、機能がアクティブになる開始時間と終了時間が構成されます。

アドバンスド: 機能フラグ名では、コロン文字 (:) は使用されていません。

要件の種類

conditions プロパティ内では、requirement_type プロパティを使用して、機能の状態を評価するときにフィルターでAnyまたはAllロジックを使用するかどうかを決定します。 requirement_type を指定しない場合の既定値は Any です。 requirement_type値は、次の動作になります。

  • Any: 機能が有効になるには、1つのフィルターがtrueとなる必要があります。
  • All: 機能を有効にするには、すべてのフィルターが true に評価される必要があります。

requirement_typeAllによって、フィルターの走査方法が変わります。

  • フィルターが一覧に表示されない場合、この機能は無効になります。
  • フィルターがリストで指定されている場合は、機能を無効にすることを指定する条件が見つかるまで走査されます。 どのフィルターも機能を無効にすることを示していない場合は、有効とみなされます。
{
    "id": "FeatureW",
    "enabled": true,
    "conditions": {
        "requirement_type": "All",
        "client_filters": [
            {
                "name": "Microsoft.TimeWindow",
                "parameters": {
                    "Start": "Sun, 01 Jun 2025 13:59:59 GMT",
                    "End": "Fri, 01 Aug 00:00:00 GMT"
                }
            },
            {
                "name": "Microsoft.Percentage",
                "parameters": {
                    "Value": "50"
                }
            }
        ]
    }
}

この例では、 FeatureW 機能フラグの requirement_type 値は All です。 その結果、機能を有効にするためには、すべてのフィルターが true と評価される必要があります。 この場合、この機能は、指定された時間枠内のユーザーの 50% に対して有効になります。

複数の構成ソースの処理

v4.3.0 以降では、Microsoft スキーマ機能フラグ (feature_management セクション) のカスタム マージを選択できます。 同じ機能フラグ ID が複数の構成ソースに表示される場合、組み込みの ConfigurationFeatureDefinitionProvider クラスのインスタンスは、構成プロバイダーの登録順序に従ってこれらの定義をマージします。 競合がある場合は、最後の機能フラグ定義が使用されます。 この動作は、.NET での既定の配列インデックスベースのマージとは異なります。

次のコードでは、依存関係の挿入によるカスタム機能フラグ構成のマージを有効にします。

IConfiguration configuration = new ConfigurationBuilder()
    .AddJsonFile("appsettings.json")
    .AddJsonFile("appsettings.prod.json")
    .Build();

services.AddSingleton(configuration);
services.AddFeatureManagement();
services.Configure<ConfigurationFeatureDefinitionProviderOptions>(o =>
{
        o.CustomConfigurationMergingEnabled = true;
});

ConfigurationFeatureDefinitionProviderのインスタンスを構築するときに、カスタムマージを有効にすることもできます。

var featureManager = new FeatureManager(
    new ConfigurationFeatureDefinitionProvider(
            configuration,
            new ConfigurationFeatureDefinitionProviderOptions
            {
                    CustomConfigurationMergingEnabled = true
            }));

動作の例:

// appsettings.json
{
    "feature_management": {
        "feature_flags": [
            { "id": "FeatureA", "enabled": true },
            { "id": "FeatureB", "enabled": false }
        ]
    }
}

// appsettings.prod.json (added later in ConfigurationBuilder)
{
    "feature_management": {
        "feature_flags": [
            { "id": "FeatureB", "enabled": true }
        ]
    }
}

カスタムマージを有効にすると、 FeatureA は有効のままになり、最後の宣言が使用されるため、 FeatureB は有効に解決されます。 カスタムマージが無効になっている既定の .NET マージを使用すると、配列はインデックスによってマージされます。 この方法では、ソースが位置によって一致しない場合、予期しない結果が生じる可能性があります。

.NET 機能管理スキーマ

以前のバージョンの機能管理ライブラリでは、プライマリ スキーマは .NET 機能管理スキーマでした。

バージョン 4.0.0 以降のライブラリでは、バリアントやテレメトリを含む新機能は、.NET 機能管理スキーマではサポートされていません。

Note

機能フラグ構成に、 feature_management セクションと FeatureManagement セクションの両方に記載されている宣言が含まれている場合は、 feature_management セクションの宣言が採用されます。

従量課金

基本的な実装では、機能管理によって、機能フラグが有効になっているかどうかを確認します。 次に、結果に基づいてアクションを実行します。 このチェックは、IsEnabledAsyncIVariantFeatureManagerメソッドを使用して行われます。

…
IVariantFeatureManager featureManager;
…
if (await featureManager.IsEnabledAsync("FeatureX"))
{
    // Do something.
}

サービス登録

機能管理は、.NET Core の依存関係の挿入に依存します。 次のコードに示すように、標準規則を使用して機能管理サービスを登録できます。

using Microsoft.FeatureManagement;

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddFeatureManagement();
    }
}

既定では、機能マネージャーは、.NET Core 構成データの feature_management または FeatureManagement セクションから機能フラグ構成を取得します。 どちらのセクションも存在しない場合、構成は空と見なされます。

Note

また、セクションを AddFeatureManagementに渡すことで、機能フラグの構成を別の構成セクションから取得するように指定することもできます。 次の例では、機能マネージャーが代わりに MyFeatureFlags というセクションから読み取る必要があることを指定します。

services.AddFeatureManagement(configuration.GetSection("MyFeatureFlags"));

依存関係の挿入

MVC で機能管理ライブラリを使用する場合は、依存関係の挿入を使用して IVariantFeatureManager を実装するオブジェクトを取得できます。

public class HomeController : Controller
{
    private readonly IVariantFeatureManager _featureManager;
    
    public HomeController(IVariantFeatureManager featureManager)
    {
        _featureManager = featureManager;
    }
}

範囲指定された機能管理サービス

AddFeatureManagementメソッドは、アプリケーション内で機能管理サービスをシングルトンとして追加します。 一部のシナリオでは、代わりに機能管理サービスをスコープサービスとして追加する必要があります。 たとえば、コンテキスト情報のために範囲指定されたサービスを消費する機能フィルターを使用する場合があります。 この場合は、 AddScopedFeatureManagement メソッドを使用する必要があります。 このメソッドにより、機能フィルターを含む機能管理サービスが範囲指定されたサービスとして追加されます。

services.AddScopedFeatureManagement();

ASP.NET Core 統合

機能管理ライブラリは、ASP.NET Core と MVC で機能を提供し、Web アプリケーションで一般的な機能フラグ シナリオを有効にします。 これらの機能は Microsoft.FeatureManagement.AspNetCore NuGet パッケージを参照することで使用できます。

コントローラーとアクション

MVC コントローラーとアクションを実行するには、特定の機能または機能の任意の一覧の 1 つを有効にする必要があります。 FeatureGateAttribute オブジェクトを使用して、この要件を満たすことができます。 FeatureGateAttribute クラスは、Microsoft.FeatureManagement.Mvc名前空間で定義されます。

[FeatureGate("FeatureX")]
public class HomeController : Controller
{
    …
}

前の例では、 HomeController クラスは FeatureXによってゲートされます。 HomeController アクションは、 FeatureX 機能が有効になっている場合にのみ実行できます。

[FeatureGate("FeatureX")]
public IActionResult Index()
{
    return View();
}

前の例では、 Index MVC アクションは、 FeatureX 機能が有効になっている場合にのみ実行できます。

無効なアクション処理

指定した機能がいずれも有効になっていないために MVC コントローラーまたはアクションがブロックされると、 IDisabledFeaturesHandler の登録済み実装が呼び出されます。 既定では、HTTP 404 エラーを返す最小限のハンドラーが登録されます。 機能フラグを登録するときに IFeatureManagementBuilder を使用して、このハンドラーをオーバーライドできます。

public interface IDisabledFeaturesHandler
{
    Task HandleDisabledFeatures(IEnumerable<string> features, ActionExecutingContext context);
}

表示

MVC ビューでは、 <feature> タグを使用してコンテンツを条件付きでレンダリングできます。 レンダリング条件は、フィーチャが有効かどうか、またはフィーチャの特定のバリアントが割り当てられているかどうかに基づいて行うことができます。 詳細については、この記事で後述 するバリアントを参照してください。

<feature name="FeatureX">
  <p>This content appears only when 'FeatureX' is enabled.</p>
</feature>
<feature name="FeatureX" variant="Alpha">
  <p>This content appears only when variant 'Alpha' of 'FeatureX' is assigned.</p>
</feature>

また、機能または一連の機能が無効になっているときにコンテンツを表示する場合は、タグ ヘルパーの評価を無効にすることもできます。 次の例のように negate="true"を指定した場合、コンテンツは FeatureX が無効になっている場合にのみレンダリングされます。

<feature negate="true" name="FeatureX">
  <p>This content appears only when 'FeatureX' is disabled.</p>
</feature>
<feature negate="true" name="FeatureX" variant="Alpha">
  <p>This content appears only when variant 'Alpha' of 'FeatureX' isn't assigned.</p>
</feature>

<feature> タグを使用して、複数のフィーチャを参照できます。 そのためには、 name 属性でフィーチャのコンマ区切りリストを指定します。

<feature name="FeatureX,FeatureY">
  <p>This content appears only when 'FeatureX' and 'FeatureY' are enabled.</p>
</feature>

既定では、機能タグがレンダリングされるには、一覧表示されたすべての機能が有効になっている必要があります。 次の例に示すように、 requirement 属性を追加することで、この動作をオーバーライドできます。

<feature name="FeatureX,FeatureY" requirement="Any">
  <p>This content appears only when 'FeatureX,' 'FeatureY,' or both are enabled.</p>
</feature>

<feature> タグを使用して、複数のバリアントを参照することもできます。 そのためには、requirementAny値を使用し、variant属性にバリアントのコンマ区切りのリストを指定します。

<feature name="FeatureX" variant="Alpha,Beta" requirement="Any">
  <p>This content appears only when variant 'Alpha' or 'Beta' of 'FeatureX' is assigned.</p>
</feature>

Note

  • バリアントを指定する場合は、 フィーチャーを 1 つだけ 指定する必要があります。
  • 複数のバリアントを指定し、requirementAnd値を使用すると、エラーが発生します。 複数のバリアントを割り当てることはできません。

<feature> タグを使用するにはタグ ヘルパーが必要です。 タグを使用するには、 _ViewImports.cshtml ファイルに機能管理タグ ヘルパーを追加します。

@addTagHelper *, Microsoft.FeatureManagement.AspNetCore

MVC フィルター

機能の状態に基づいて条件付きで適用する MVC アクション フィルターを設定できます。 これらのフィルターを設定するには、機能に対応した方法でフィルターを登録します。 機能管理パイプラインでは、 IAsyncActionFilter インターフェイスを実装する非同期 MVC アクション フィルターがサポートされています。

services.AddMvc(o => 
{
    o.Filters.AddForFeature<SomeMvcFilter>("FeatureX");
});

上記のコードは、 SomeMvcFilterという名前の MVC フィルターを登録します。 このフィルターは、 FeatureX が有効になっている場合にのみ MVC パイプライン内でトリガーされます。

Razor ページ

MVC Razor ページでは、特定の機能または機能の任意の一覧の 1 つを実行するために有効にする必要があります。 この要件は、 FeatureGateAttribute オブジェクトを使用して追加できます。 FeatureGateAttribute クラスは、Microsoft.FeatureManagement.Mvc名前空間で定義されます。

[FeatureGate("FeatureX")]
public class IndexModel : PageModel
{
    public void OnGet()
    {
    }
}

上記のコードは、 FeatureX が有効になっている必要がある Razor ページを設定します。 この機能が有効になっていない場合、ページによって HTTP 404 (NotFound) の結果が生成されます。

Razor ページで FeatureGateAttribute オブジェクトを使用する場合は、ページ ハンドラーの種類に FeatureGateAttribute を配置する必要があります。 個々のハンドラー メソッドに配置することはできません。

アプリケーションの構築

機能管理ライブラリを使用して、機能の状態に基づいて条件付きで実行されるアプリケーション ブランチとミドルウェアを追加できます。

app.UseMiddlewareForFeature<ThirdPartyMiddleware>("FeatureX");

前のコードでは、アプリケーションは、 FeatureX 機能が有効になっている場合にのみ、要求パイプラインに表示されるミドルウェア コンポーネントを追加します。 実行時に機能が有効または無効になっている場合は、ミドルウェア パイプラインを動的に変更できます。

次のコードに示すように、この機能は、機能に基づいてアプリケーション全体を分岐する、より汎用的な機能から構築されます。

app.UseForFeature(featureName, appBuilder => 
{
    appBuilder.UseMiddleware<T>();
});

機能フィルターを実装する

機能フィルターを作成すると、定義した条件に基づいて機能を有効にする方法を得られます。 機能フィルターを実装するには、 IFeatureFilter インターフェイスを実装する必要があります。 IFeatureFilter には EvaluateAsync という名前の単一のメソッドがあります。 機能が機能フィルターに対して有効であることを指定すると、EvaluateAsync メソッドが呼び出されます。 EvaluateAsynctrueを返す場合は、この機能を有効にする必要があります。

次のコードは、 MyCriteriaFilterと呼ばれるカスタマイズされた機能フィルターを追加する方法を示しています。

services.AddFeatureManagement()
        .AddFeatureFilter<MyCriteriaFilter>();

AddFeatureFilter<T>返されるIFeatureManagementBuilder実装でAddFeatureManagementを呼び出すことで、機能フィルターを登録できます。 機能フィルターは、機能フラグの追加に使用するサービス コレクション内のサービスにアクセスできます。 依存関係の挿入を使用して、これらのサービスを取得できます。

Note

機能フラグ設定 ( appsettings.jsonなど) でフィルターを参照する場合は、型名の Filter 部分を省略する必要があります。 詳細については、この記事で後述 する「エイリアス属性のフィルター」を参照してください。

パラメーター化機能フィルター

一部の機能フィルターでは、機能を有効にする必要があるかどうかを評価するためにパラメーターが必要です。 たとえば、ブラウザー機能フィルターは、特定のブラウザー セットの機能を有効にする場合があります。 Microsoft Edge ブラウザーと Chrome ブラウザーでは機能を有効にできますが、Firefox では有効にしない場合があります。

このフィルター処理を実装するために、パラメーターを期待するように機能フィルターを設計できます。 これらのパラメーターは、機能構成で指定します。 コードでは、FeatureFilterEvaluationContextIFeatureFilter.EvaluateAsync パラメーターを使用してアクセスします。

public class FeatureFilterEvaluationContext
{
    /// <summary>
    /// The name of the feature being evaluated
    /// </summary>
    public string FeatureName { get; set; }

    /// <summary>
    /// The settings provided for the feature filter to use when evaluating whether the feature should be enabled
    /// </summary>
    public IConfiguration Parameters { get; set; }
}

FeatureFilterEvaluationContext クラスには、Parametersという名前のプロパティがあります。 このプロパティのパラメーターは、機能を有効にするかどうかを評価するときに機能フィルターで使用できる未加工の構成を表します。 ブラウザー機能フィルターの例では、フィルターで Parameters プロパティを使用して、機能に対して指定されている許可されているブラウザーのセットを抽出できます。 フィルターは、要求がこれらのブラウザーのいずれかからのものであるかどうかを確認できます。

[FilterAlias("Browser")]
public class BrowserFilter : IFeatureFilter
{
    …

    public Task<bool> EvaluateAsync(FeatureFilterEvaluationContext context)
    {
        BrowserFilterSettings settings = context.Parameters.Get<BrowserFilterSettings>() ?? new BrowserFilterSettings();

        //
        // Use the settings to check whether the request is from a browser in BrowserFilterSettings.AllowedBrowsers.
    }
}

フィルター エイリアス属性

機能フラグの機能フィルターを登録する場合、構成で使用するエイリアスは、 Filter サフィックスがある場合は削除された機能フィルターの種類の名前です。 設定では、たとえば、MyCriteriaFilterMyCriteria として参照する必要があります。

{
    "id": "MyFeature",
    "enabled": true,
    "conditions": {
        "client_filters": [
            {
                "name": "MyCriteria"
            }
        ]
    }
}

この名前は、 FilterAliasAttribute クラスを使用してオーバーライドできます。 構成で使用する名前を宣言して、機能フラグ内の機能フィルターを参照するには、この属性を使用して機能フィルターを装飾します。

不足している機能フィルター

特定の機能フィルターに対して機能を有効にするように構成するとします。 そのフィーチャーフィルターが登録されていない場合は、フィーチャーが評価されるときに例外がスローされます。 次のコードに示すように、機能管理オプションを使用して例外を無効にすることができます。

services.Configure<FeatureManagementOptions>(options =>
{
    options.IgnoreMissingFeatureFilters = true;
});

HttpContext を使用する

機能フィルターは、HTTP 要求のプロパティに基づいて機能を有効にする必要があるかどうかを評価できます。 このチェックは、HTTP コンテキストを調べることによって実行されます。 次のコードに示すように、機能フィルターでは、依存関係の挿入を使用して HTTP コンテキストへの参照を取得し、 IHttpContextAccessorの実装を取得できます。

public class BrowserFilter : IFeatureFilter
{
    private readonly IHttpContextAccessor _httpContextAccessor;

    public BrowserFilter(IHttpContextAccessor httpContextAccessor)
    {
        _httpContextAccessor = httpContextAccessor ?? throw new ArgumentNullException(nameof(httpContextAccessor));
    }
}

IHttpContextAccessor実装を使用できるようにするには、起動時に依存関係挿入コンテナーに追加する必要があります。 次のメソッドを使用して、 IServiceCollection サービスに実装を登録できます。

public void ConfigureServices(IServiceCollection services)
{
    …
    services.AddHttpContextAccessor();
    …
}

Advanced:IHttpContextAccessor サーバー側 Blazor アプリの Razor コンポーネントでは、 HttpContext を使用しないでください。 Blazor アプリで HTTP コンテキストを渡すための 推奨される方法 は、データをスコープ付きサービスにコピーすることです。 Blazor アプリの場合は、 AddScopedFeatureManagement を使用して機能管理サービスを登録する必要があります。 詳細については、この記事の前 の「範囲指定された機能管理サービス」を参照してください。

機能評価のコンテキストを提供する

コンソール アプリケーションでは、機能フィルターを使用して機能をオンにするかどうかを確認できる HttpContext などのアンビエント コンテキストはありません。 この場合、アプリケーションは、機能フィルターで使用するために、機能管理システムへのコンテキストを表すオブジェクトを提供する必要があります。 IVariantFeatureManager.IsEnabledAsync<TContext>(string featureName, TContext appContext)を使用して、このコンテキストを提供できます。 フィーチャの状態を評価するために、機能フィルターは、フィーチャ マネージャーに提供する appContext オブジェクトを使用できます。

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

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

コンテキスト機能フィルター

コンテキスト機能フィルターは IContextualFeatureFilter<TContext> インターフェイスを実装します。 これらの特殊な機能フィルターは、 IVariantFeatureManager.IsEnabledAsync<TContext> が呼び出されたときに渡されるコンテキストを利用できます。 TContextIContextualFeatureFilter<TContext>型パラメーターは、フィルターで処理できるコンテキスト型を記述します。 コンテキスト機能フィルターを開発する場合は、コンテキストの種類を指定することで、フィルターを使用するための要件を確立できます。

すべての型は Object クラスの子孫であるため、 IContextualFeatureFilter<object> を実装するフィルターは、指定されたコンテキストに対して呼び出すことができます。 次のコードは、特定のコンテキスト機能フィルターの例を示しています。 このコードでは、アカウントが有効なアカウントの構成済みリストに含まれる場合、機能が有効になります。

public interface IAccountContext
{
    string AccountId { get; set; }
}

[FilterAlias("AccountId")]
class AccountIdFilter : IContextualFeatureFilter<IAccountContext>
{
    public Task<bool> EvaluateAsync(FeatureFilterEvaluationContext featureEvaluationContext, IAccountContext accountId)
    {
        //
        // Evaluate whether the feature should be on by using the IAccountContext that's provided.
    }
}

AccountIdFilter クラスでは、機能の状態を評価できるように、IAccountContextを実装するオブジェクトを指定する必要があります。 この機能フィルターを使用する場合、呼び出し元は、渡されたオブジェクトが IAccountContextを実装していることを確認する必要があります。

Note

1 つの種類を実装できるのは、1 つの機能フィルター インターフェイスのみです。 1 つ以上の機能フィルター インターフェイスを実装する機能フィルターを追加しようとすると、 ArgumentException 例外が発生します。

同じエイリアスでコンテキスト フィルターと非コンテキスト フィルターを使用する

IFeatureFilterIContextualFeatureFilterを実装するフィルターは、同じエイリアスを共有できます。 具体的には、0 個または 1 つのIFeatureFilter実装で 1 つのフィルター エイリアスを共有し、に適用可能なフィルターが 1 つ以上ある場合は、0 または IContextualFeatureFilter<ContextType>ContextType の実装を使用できます。

同じ名前のコンテキスト フィルターと非コンテキスト フィルターがアプリケーションに登録されている場合にフィルターを選択するプロセスを理解するには、次の例を考えてみましょう。

3 つのフィルターは、 SharedFilterName エイリアスを共有します。

  • という非コンテキスト フィルター FilterA
  • FilterB コンテキストを受け入れるTypeBというコンテキスト フィルター
  • FilterC コンテキストを受け入れるTypeCというコンテキスト フィルター

MyFeatureと呼ばれる機能フラグは、その構成でSharedFilterName機能フィルターを使用します。

3 つのフィルターがすべて登録されている場合:

  • IsEnabledAsync("MyFeature")を呼び出すと、FilterA フィルターを使用して機能フラグが評価されます。
  • IsEnabledAsync("MyFeature", context)を呼び出すとき:
    • contextの種類がTypeBの場合は、FilterBが使用されます。
    • contextの種類がTypeCの場合は、FilterCが使用されます。
    • contextの種類がTypeFの場合は、FilterAが使用されます。

組み込み機能フィルター

Microsoft.FeatureManagement パッケージには、PercentageFilterTimeWindowFilterContextualTargetingFilterTargetingFilterなど、いくつかの機能フィルターがあります。 TargetingFilterメソッドを使用して機能管理を登録すると、を除くすべてのフィルターが自動的に追加AddFeatureManagementTargetingFilter は、 WithTargeting メソッドを使用して追加されます。 詳細については、この記事の後半の 「ターゲット設定」を参照してください。

組み込み機能フィルターにはそれぞれ独自のパラメーターがあります。 次のセクションでは、これらの機能フィルターについて説明し、例を示します。

Microsoft.Percentage

Microsoft.Percentage フィルターは、設定された割合に基づいて機能を有効にする方法を提供します。

{
    "id": "EnhancedPipeline",
    "enabled": true,
    "conditions": {
        "client_filters": [
            {
                "name": "Microsoft.Percentage",
                "parameters": {
                    "Value": 50
                }
            }
        ]
    }
}

Microsoft.TimeWindow

Microsoft.TimeWindow フィルターは、時間枠に基づいて機能を有効にする方法を提供します。

  • End値のみを指定した場合、その時点まで機能がオンと見なされます。
  • Start値のみを指定した場合、その時点以降のすべてのポイントでフィーチャーがオンと見なされます。
{
    "id": "EnhancedPipeline",
    "enabled": true,
    "conditions": {
        "client_filters": [
            {
                "name": "Microsoft.TimeWindow",
                "parameters": {
                    "Start": "Sun, 01 Jun 2025 13:59:59 GMT",
                    "End": "Fri, 01 Aug 2025 00:00:00 GMT"
                }
            }
        ]
    }
}

定期的に時間枠を適用するようにフィルターを構成できます。 この機能は、1 日または特定の曜日のトラフィックが少ない、またはトラフィックの多い時間帯に機能を有効にする必要がある場合に役立ちます。 個々の時間枠を定期的な時間枠に展開するには、 Recurrence パラメーターを使用して繰り返しルールを指定します。

Note

繰り返しを使用するには、 Start 値と End 値を指定する必要があります。 繰り返しの場合、 End 値の日付部分では、フィルターをアクティブと見なす終了日は指定されません。 代わりに、フィルターは開始日を基準とした終了日を使用して、繰り返される時間枠の期間を定義します。

{
    "id": "EnhancedPipeline",
    "enabled": true,
    "conditions": {
        "client_filters": [
            {
                "name": "Microsoft.TimeWindow",
                "parameters": {
                    "Start": "Fri, 22 Mar 2024 20:00:00 GMT",
                    "End": "Sat, 23 Mar 2024 02:00:00 GMT",
                    "Recurrence": {
                        "Pattern": {
                            "Type": "Daily",
                            "Interval": 1
                        },
                        "Range": {
                            "Type": "NoEnd"
                        }
                    }
                }
            }
        ]
    }
}

Recurrence設定は、次の 2 つの部分で構成されます。

  • Pattern設定では、時間枠を繰り返す頻度を指定します。
  • Range設定では、繰り返しパターンが繰り返される期間を指定します。

繰り返しパターン

繰り返しパターンには、DailyWeekly の 2 種類があります。 たとえば、時間枠は、毎日、3 日ごと、毎週月曜日、または他の金曜日に繰り返すことができます。

型に応じて、 Pattern 設定の特定のフィールドが必須、省略可能、または無視されます。

  • Daily

    1 日の繰り返しパターンでは、各発生の間に指定した日数に基づいて時間枠が繰り返されます。

    プロパティ 関連性 説明
    Type 必須 繰り返しパターンの種類。 Daily に設定する必要があります。
    Interval 省略可能 各出現間隔の日数。 既定値は 1 です。
  • Weekly

    週単位の繰り返しパターンにより、同じ曜日または曜日に時間枠が繰り返されます。 ただし、各出現回数の間の週数を指定できます。

    プロパティ 関連性 説明
    Type 必須 繰り返しパターンの種類。 Weekly に設定する必要があります。
    DaysOfWeek 必須 イベントが発生する曜日。
    Interval 省略可能 各セットの出現間の週数。 既定値は 1 です。
    FirstDayOfWeek 省略可能 週の最初の日として使用する日。 既定値は Sunday です。

    次の例では、月曜日と火曜日ごとに時間枠を繰り返します。

    "Pattern": {
        "Type": "Weekly",
        "Interval": 2,
        "DaysOfWeek": ["Monday", "Tuesday"]
    }
    

Note

Start値は、繰り返しパターンに適合する有効な最初の出現である必要があります。 また、時間枠の期間は、発生する頻度よりも長くすることはできません。 たとえば、25 時間の時間枠を毎日繰り返すことはできません。

繰り返しの範囲

繰り返し範囲には、 NoEndEndDateNumberedの 3 種類があります。

  • NoEnd

    NoEnd の範囲では、繰り返しが無期限に発生します。

    プロパティ 関連性 説明
    Type 必須 繰り返し範囲の種類。 NoEnd に設定する必要があります。
  • EndDate

    EndDate の範囲は、終了日まで該当するパターンに当てはまるすべての日に発生するように時間枠に影響します。

    プロパティ 関連性 説明
    Type 必須 繰り返し範囲の種類。 EndDate に設定する必要があります。
    EndDate 必須 パターンの適用を停止する日付と時刻。 最後の出現の開始時刻が終了日より前の場合、その発生の終了時刻はそれ以上長く続く可能性があります。

    次の例では、時間枠は 2024 年 4 月 1 日に最後に発生するまで毎日繰り返されます。

    "Start": "Fri, 22 Mar 2024 18:00:00 GMT",
    "End": "Fri, 22 Mar 2024 20:00:00 GMT",
    "Recurrence":{
        "Pattern": {
            "Type": "Daily",
            "Interval": 1
        },
        "Range": {
            "Type": "EndDate",
            "EndDate": "Mon, 1 Apr 2024 20:00:00 GMT"
        }
    }
    
  • Numbered

    Numbered範囲を指定すると、指定した回数だけ時間枠が発生します。

    プロパティ 関連性 説明
    Type 必須 繰り返し範囲の種類。 Numbered に設定する必要があります。
    NumberOfOccurrences 必須 出現回数。

    次の例では、月曜日と火曜日に時間枠が繰り返され、合計で 3 回出現します。これは次の日付で発生します。

    • 4 月 1 日 (月)
    • 火曜日, 4 月 2 日
    • 4 月 8 日 (月)
    "Start": "Mon, 1 Apr 2024 18:00:00 GMT",
    "End": "Mon, 1 Apr 2024 20:00:00 GMT",
    "Recurrence":{
        "Pattern": {
            "Type": "Weekly",
            "Interval": 1,
            "DaysOfWeek": ["Monday", "Tuesday"]
        },
        "Range": {
            "Type": "Numbered",
            "NumberOfOccurrences": 3
        }
    }
    

繰り返しルールを作成するには、 PatternRange の両方の設定を指定する必要があります。 どのパターンの種類でも、どの範囲の種類でも機能します。

詳細:Start プロパティのタイム ゾーン オフセットが繰り返し設定に適用されます。

Microsoft.Targeting

Microsoft.Targeting フィルターは、対象ユーザーに対して機能を有効にする方法を提供します。 ターゲット設定の詳細については、この記事の後半の 「ターゲット設定」を参照してください。

フィルター パラメーターには、機能にアクセスできるユーザーを記述する Audience オブジェクトが含まれます。 Audience オブジェクト内で、ユーザー、グループ、除外されたユーザーとグループ、およびユーザー ベースの既定の割合を指定できます。

Groups セクションに一覧表示するグループ オブジェクトごとに、グループのメンバーがアクセスできる割合も指定する必要があります。

ユーザーごとに、この機能は次のように評価されます。

  • ユーザーが除外されている場合、この機能はユーザーに対して無効になります。 次の方法でユーザーを除外できます。

    • Exclusion セクションの Users の下に名前をリストで指定する。
    • Groups セクションのExclusionの下に属しているグループを一覧表示します。
  • ユーザーが除外されていない場合、次のいずれかの条件が満たされている場合、この機能は有効になります。

    • ユーザーは、 Users セクションに一覧表示されます。
    • ユーザーは、任意のグループ ロールアウトの含まれる割合内にあります。
    • ユーザーは、デフォルトの展開割合に当てはまります。
  • 上記のいずれのケースも適用されない場合は、ユーザーに対して機能が無効になります。 たとえば、ユーザーが指定されたパーセンテージに含まれていない場合、この機能は無効になります。

{
    "id": "EnhancedPipeline",
    "enabled": true,
    "conditions": {
        "client_filters": [
            {
                "name": "Microsoft.Targeting",
                "parameters": {
                    "Audience": {
                        "Users": [
                            "Jeff",
                            "Alicia"
                        ],
                        "Groups": [
                            {
                                "Name": "Ring0",
                                "RolloutPercentage": 100
                            },
                            {
                                "Name": "Ring1",
                                "RolloutPercentage": 50
                            }
                        ],
                        "DefaultRolloutPercentage": 20,
                        "Exclusion": {
                            "Users": [
                                "Ross"
                            ],
                            "Groups": [
                                "Ring2"
                            ]
                        }
                    }
                }
            }
        ]
    }
}

機能フィルターのエイリアスの名前空間

すべての組み込み機能フィルターエイリアスは、 Microsoft 機能フィルター名前空間にあります。 この名前空間では、同じエイリアスを共有する他の機能フィルターとの競合を防ぐことができます。 機能フィルター名前空間のセグメントは、 . 文字によって分割されます。 機能フィルターは、 Microsoft.Percentageなどの完全修飾エイリアスで参照できます。 または、 Percentageなど、最後のセグメントを参照することもできます。

対象設定

ターゲット設定は、ユーザー ベースに新しい機能を段階的にロールアウトするために使用できる機能管理戦略です。 この戦略は、対象ユーザーと呼ばれる一連のユーザーを対象設定するという概念に基づいて構築されています。 対象ユーザーは、特定のユーザー、グループ、除外されたユーザーとグループ、およびユーザー ベース全体の指定された割合で構成されます。 対象ユーザーに含まれるグループは、メンバーの合計数に対する割合にさらに分けることができます。

次の手順は、ベータと呼ばれる新機能の段階的なロールアウトの例を示しています。

  1. 個々のユーザー Jeff と Alicia には、ベータ機能へのアクセス権が付与されます。
  2. 別のユーザーであるマークは、オプトイン要求をして、含まれました。
  3. Ring1 グループのユーザーの 20% がベータ機能に含まれています。
  4. 含まれる Ring1 ユーザーの数は、最大 100% に増加します。
  5. ユーザー ベースの 5% がベータ機能に含まれています。
  6. ロールアウト率は、機能を完全にロールアウトするために最大 100% まで増加します。

このライブラリでは、組み込みの Microsoft.Targeting 機能フィルターを使用して機能をロールアウトするためのこの戦略がサポートされています。

Web アプリケーションでのターゲット設定

ターゲット機能フィルターを使用する Web アプリケーションの例については、 FeatureFlagDemo サンプル プロジェクトを参照してください。

アプリケーションで TargetingFilter の使用を開始するには、他の機能フィルターと同様に、アプリケーションのサービス コレクションに追加する必要があります。 他の組み込みフィルターとは異なり、 TargetingFilter は、アプリケーションのサービス コレクションに追加される別のサービスに依存します。 そのサービスは ITargetingContextAccessor 実装です。

Microsoft.FeatureManagement.AspNetCore ライブラリには、要求の値からターゲット情報を抽出するITargetingContextAccessorHttpContextが用意されています。 既定のターゲット コンテキスト アクセサーは、WithTargetingの非ジェネリック IFeatureManagementBuilder オーバーロードを使用してターゲット設定を設定するときに使用できます。

既定のターゲット コンテキスト アクセサーとTargetingFilterを登録するには、WithTargetingIFeatureManagementBuilderを呼び出します。

services.AddFeatureManagement()
        .WithTargeting();

WithTargeting<T> を呼び出して、ITargetingContextAccessorTargetingFilter のカスタマイズされた実装を登録することもできます。 次のコードは、TargetingFilterと呼ばれるITargetingContextAccessorの実装でExampleTargetingContextAccessorを使用するように Web アプリケーションの機能管理を設定します。

services.AddFeatureManagement()
        .WithTargeting<ExampleTargetingContextAccessor>();

ITargetingContextAccessor

Web アプリケーションで TargetingFilter を使用するには、 ITargetingContextAccessor の実装が必要です。 この要件の背後にある理由は、評価をターゲットにするためには、ユーザーに関する情報などのコンテキスト情報が必要であるという点です。 この情報は、 TargetingContext クラスのインスタンスに格納されます。 アプリケーションによって、要求の HTTP コンテキストやデータベースなど、さまざまな場所からこの情報が抽出されます。

アプリケーションの HTTP コンテキストからターゲット コンテキスト情報を抽出する例については、DefaultHttpTargetingContextAccessor パッケージのMicrosoft.FeatureManagement.AspNetCoreを参照してください。 次の情報が抽出されます。

  • HttpContext.User プロパティからの情報のターゲット設定
  • UserId Identity.Name フィールドからの情報
  • Groups 型のクレームからの情報 Role

この実装は、 IHttpContextAccessorの使用に依存します。 IHttpContextAccessorの詳細については、この記事で前述した HttpContext の使用に関する記事を参照してください。

コンソール アプリケーションでのターゲット設定

対象設定フィルターは、機能をオンにする必要があるか評価するために、ターゲット設定コンテキストに依存します。 このターゲット コンテキストには、評価対象のユーザーやユーザーが属しているグループなどの情報が含まれます。 コンソール アプリケーションでは、通常、この情報をターゲット フィルターに渡すために使用できるアンビエント コンテキストはありません。 その結果、 FeatureManager.IsEnabledAsyncを呼び出すときに直接渡す必要があります。 この種類のコンテキストは、 ContextualTargetingFilterを使用してサポートされます。 ターゲット コンテキストを機能マネージャーに送信する必要があるアプリケーションでは、TargetingFilter. の代わりに ContextualTargetingFilter を使用する必要があります。

ContextualTargetingFilterIContextualTargetingFilter<ITargetingContext>を実装するため、ITargetingContextの実装をIVariantFeatureManager.IsEnabledAsyncに渡して、機能を評価して有効にする必要があります。

IVariantFeatureManager fm;
…
// The userId and groups variables are defined earlier in the application.
TargetingContext targetingContext = new TargetingContext
{
   UserId = userId,
   Groups = groups
};

await fm.IsEnabledAsync(featureName, targetingContext);

ContextualTargetingFilter では機能フィルターエイリアス Microsoft.Targetingが使用されるため、このフィルターの構成は、この記事の前半の Microsoft.Targeting の情報と一致します。

コンソール アプリケーションで ContextualTargetingFilter を使用する例については、 TargetingConsoleApp サンプル プロジェクトを参照してください。

ターゲットの評価オプション

すべての機能に対象設定評価を実行する方法をカスタマイズするオプションが用意されています。 これらのオプションは、機能管理を設定するときに構成できます。

services.Configure<TargetingEvaluationOptions>(options =>
{
    options.IgnoreCase = true;
});

対象設定の除外

対象ユーザーを定義するときに、対象ユーザーからユーザーとグループを除外できます。 この機能は、機能をユーザーのグループにロールアウトするが、ロールアウトから少数のユーザーまたはグループを除外する必要がある場合に便利です。 除外するユーザーとグループを指定するには、対象ユーザーの Exclusion プロパティを使用します。

"Audience": {
    "Users": [
        "Jeff",
        "Alicia"
    ],
    "Groups": [
        {
            "Name": "Ring0",
            "RolloutPercentage": 100
        }
    ],
    "DefaultRolloutPercentage": 0,
    "Exclusion": {
        "Users": [
            "Mark"
        ]
    }
}

上記のコードでは、 Jeff および Alicia という名前のユーザーに対して機能を有効にします。 この機能は、 Ring0 という名前のグループ内のユーザーにも有効になります。 ただし、そのユーザーがMark グループに含まれている場合でも、Ring0という名前のユーザーに対してこの機能は無効になります。 除外は対象設定フィルターの残りの部分よりも優先されます。

バリエーション

アプリケーションに新しい機能を追加する場合、その機能には複数のデザイン オプションが提案されている場合があります。 A/B テストは、設計を決定するための一般的なソリューションを提供します。 A/B テストでは、ユーザー ベースの異なるセグメントに異なるバージョンの機能を提供し、ユーザーの操作に基づいてバージョンを選択する必要があります。 .NET 機能管理ライブラリでは、バリアントを使用して機能のさまざまな構成を表すことで、A/B テストを実装できます。

バリアントは、機能フラグが基本的なオン/オフ フラグ以上になる方法を提供します。 バリアントは、文字列、数値、ブール値、または構成オブジェクトであってもかまいません機能フラグの値を表します。 バリアントを宣言する機能フラグでは、各バリアントを使用する状況を定義する必要があります。 詳細については、この記事の後半にある「バリアントの割り当て」を参照してください。

public class Variant
{
    /// <summary>
    /// The name of the variant
    /// </summary>
    public string Name { get; set; }

    /// <summary>
    /// The configuration of the variant
    /// </summary>
    public IConfigurationSection Configuration { get; set; }
}

バリアントを取得する

各機能について、GetVariantAsync インターフェイスの IVariantFeatureManager メソッドを使用してバリアントを取得できます。

…
IVariantFeatureManager featureManager;
…
Variant variant = await featureManager.GetVariantAsync("MyVariantFeatureFlag", CancellationToken.None);

IConfigurationSection variantConfiguration = variant.Configuration;

// Do something with the resulting variant and its configuration.

バリアントを取得した後は、その構成をバリアントの IConfigurationSection プロパティからConfigurationの実装として直接使用できます。 もう 1 つのオプションは、.NET 構成バインド パターンを使用して、構成をオブジェクトにバインドすることです。

IConfigurationSection variantConfiguration = variant.Configuration;

MyFeatureSettings settings = new MyFeatureSettings();

variantConfiguration.Bind(settings);

返されるバリアントは、評価対象のユーザーによって異なります。 TargetingContextのインスタンスからユーザーに関する情報を取得できます。 このコンテキストは、 GetVariantAsyncを呼び出すときに渡すことができます。 または、登録されている場合は、 ITargetingContextAccessor の実装から自動的に取得できます。

バリアント機能フラグの宣言

標準機能フラグと比較すると、バリアント機能フラグには、 variantsallocationの 2 つの追加プロパティがあります。 variants プロパティは、フィーチャーに対して定義されたバリアントを含む配列です。 allocation プロパティは、これらのバリアントを機能に割り当てる方法を定義します。 標準機能フラグの宣言と同様に、JSON ファイルでバリアント機能フラグを設定できます。 次のコードは、バリアント機能フラグの例です。

{
    "feature_management": {
        "feature_flags": [
            {
                "id": "MyVariantFeatureFlag",
                "enabled": true,
                "allocation": {
                    "default_when_enabled": "Small",
                    "group": [
                        {
                            "variant": "Big",
                            "groups": [
                                "Ring1"
                            ]
                        }
                    ]
                },
                "variants": [
                    { 
                        "name": "Big"
                    },  
                    { 
                        "name": "Small"
                    } 
                ]
            }
        ]
    }
}

バリアントの定義

各バリアントには名前と構成の 2 つのプロパティがあります。 名前は特定のバリアントを指すのに使われ、構成はそのバリアントの値です。 configuration_value プロパティを使用して、構成を指定できます。 configuration_value プロパティは、文字列、数値、ブール値、または構成オブジェクトを指定できるインライン構成です。 configuration_value プロパティを構成しない場合、返されるバリアントのConfiguration プロパティはnull

フィーチャーに使用可能なすべてのバリアントを指定するには、 variants プロパティの下に一覧表示します。

{
    "feature_management": {
        "feature_flags": [
            {
                "id": "MyVariantFeatureFlag",
                "variants": [
                    { 
                        "name": "Big", 
                        "configuration_value": {
                            "Size": 500
                        }
                    },  
                    { 
                        "name": "Small", 
                        "configuration_value": {
                            "Size": 300
                        }
                    } 
                ]
            }
        ]
    }
}

バリアントの割り当て

フィーチャーのバリアントを割り当てるには、フィーチャーの allocation プロパティを使用します。

"allocation": { 
    "default_when_enabled": "Small", 
    "default_when_disabled": "Small",  
    "user": [ 
        { 
            "variant": "Big", 
            "users": [ 
                "Marsha" 
            ] 
        } 
    ], 
    "group": [ 
        { 
            "variant": "Big", 
            "groups": [ 
                "Ring1" 
            ] 
        } 
    ],
    "percentile": [ 
        { 
            "variant": "Big", 
            "from": 0, 
            "to": 10 
        } 
    ], 
    "seed": "13973240" 
},
"variants": [
    { 
        "name": "Big", 
        "configuration_value": "500px"
    },  
    { 
        "name": "Small", 
        "configuration_value": "300px"
    } 
]

allocation設定には、次のプロパティがあります。

プロパティ 説明
default_when_disabled 機能が無効と見なされている間にバリアントが要求されたときに使用するバリアント。
default_when_enabled 機能が有効と見なされ、他のバリアントがユーザーに割り当てられていないときにバリアントが要求されたときに使用するバリアント。
user バリアントとバリアントを割り当てるユーザーの一覧。
group バリアントとグループの一覧。 バリアントは、現在のユーザーが少なくとも 1 つのグループに含まれている場合に割り当てられます。
percentile バリアントと、そのバリアントの割り当てに適合するように計算されたユーザーのパーセンテージの範囲。
seed percentileのパーセンテージ計算の基となる値。 同じ seed 値が使用されている場合、特定のユーザーのパーセンテージ計算はすべての機能で同じです。 seed値が指定されていない場合は、機能名に基づいて既定のシードが作成されます。

機能が有効になっていない場合、機能マネージャーは、 default_when_disabled に指定されたバリアントを現在のユーザーに割り当てます。 前の例では、その機能は Small と呼ばれます。

この機能が有効になっている場合は、機能マネージャーは usergrouppercentile の割り当てを順番に確認してバリアントを割り当てます。 前の例では、次の場合に、指定したバリアント ( Big) がユーザーに割り当てられます。

  • 評価対象のユーザーには、 Marshaという名前が付けられます。
  • ユーザーが Ring1 グループにいます。
  • ユーザーは0パーセンタイルと10パーセンタイルの間に位置しています。

これらの割り当てが一致しない場合、 default_when_enabled バリアントがユーザーに割り当てられます。 この例では、そのバリアントは Small

割り当てロジックは、 Microsoft.Targeting 機能フィルターに使用するロジックに似ています。 ただし、ターゲット設定に存在するパラメーターの中には、割り当てに含まれていないパラメーターもあれば、その逆もあります。 対象設定と割り当ての結果は関係ありません。

Note

機能バリアントを割り当てるには、ITargetingContextAccessor メソッドを呼び出してWithTargeting<T>を登録する必要があります。

バリアントを使用して有効な状態をオーバーライドする

機能フラグの有効な状態をオーバーライドするためにバリアントを使用できます。 この機能を利用すると、機能フラグの評価を拡張できます。 バリアントを持つフラグを IsEnabledAsync する呼び出し中に、機能マネージャーは、現在のユーザーに割り当てられているバリアントが結果をオーバーライドするように構成されているかどうかを確認します。

省略可能なバリアント 型のプロパティ status_overrideを使用してオーバーライドを実装できます。 このプロパティには、次の値を指定できます。

  • None: バリアントは、フラグが有効と見なされるか無効と見なされるかには影響しません。 既定値は None です。
  • Enabled: バリアントを選択すると、機能フラグは有効として評価されます。
  • Disabled: バリアントを選択すると、機能フラグは無効として評価されます。

enabledfalse状態で機能をオーバーライドすることはできません。

バイナリバリアントで機能フラグを使用する場合は、 status_override プロパティが役立ちます。 アプリケーションでは、 IsEnabledAsyncFeatureGateAttribute などの API を引き続き使用できます。 ただし、パーセンタイルの割り当てやパーセンテージ計算にシード値を使用するなど、バリアントに付属する特徴の恩恵を受けることもできます。

{
    "id": "MyVariantFeatureFlag",
    "enabled": true,
    "allocation": {
        "percentile": [
            {
                "variant": "On",
                "from": 10,
                "to": 20
            }
        ],
        "default_when_enabled":  "Off",
        "seed": "Enhanced-Feature-Group"
    },
    "variants": [
        {
            "name": "On"
        },
        {
            "name": "Off",
            "status_override": "Disabled"
        }
    ]
}

前の例では、この機能は常に有効になっています。 現在のユーザーが計算されたパーセンタイル範囲の 10 から 20 の範囲内にある場合は、 On バリアントが返されます。 それ以外の場合は、 Off バリアントが返され、 status_override 値が Disabledされているため、機能は無効と見なされます。

依存関係挿入のバリアント

依存関係の挿入と共にバリアント機能フラグを使用して、サービスのさまざまな実装を異なるユーザーに公開できます。 IVariantServiceProvider<TService> インターフェイスは、この組み合わせを実現する方法を提供します。

IVariantServiceProvider<IAlgorithm> algorithmServiceProvider;
...

IAlgorithm forecastAlgorithm = await algorithmServiceProvider.GetServiceAsync(cancellationToken); 

前のコードでは、 IVariantServiceProvider<IAlgorithm> 実装は依存関係挿入コンテナーから IAlgorithm の実装を取得します。 選択した実装は次に依存します。

  • IAlgorithm サービスが登録されている機能フラグ。
  • その機能に割り当てられたバリアント。

IVariantServiceProvider<T>実装は、次の例に示すように、IFeatureManagementBuilder.WithVariantService<T>(string featureName)を呼び出すことによってアプリケーションで使用できます。 このコードの呼び出しにより、サービス コレクションで IVariantServiceProvider<IAlgorithm> を使用できるようになります。

services.AddFeatureManagement() 
        .WithVariantService<IAlgorithm>("ForecastAlgorithm");

IAlgorithmなどの add メソッドを使用して、services.AddSingleton<IAlgorithm, SomeImplementation>()の各実装を個別に追加する必要があります。 IAlgorithmが使用するIVariantServiceProviderの実装は、ForecastAlgorithmバリアント機能フラグによって異なります。 IAlgorithmの実装がサービス コレクションに追加されていない場合、IVariantServiceProvider<IAlgorithm>.GetServiceAsync()null結果を含むタスクを返します。

{
    // The example variant feature flag
    "id": "ForecastAlgorithm",
    "enabled": true,
    "variants": [
        { 
            "Name": "AlgorithmBeta" 
        },
        ...
    ] 
}

バリアント サービスエイリアス属性

バリアント サービス プロバイダーは、実装の型名を用いて割り当てられたバリアントを特定します。 バリアント サービスが VariantServiceAliasAttribute で修飾されている場合は、このバリアント サービスを参照するために、この属性で宣言されている名前を構成で使用する必要があります。

[VariantServiceAlias("Beta")]
public class AlgorithmBeta : IAlgorithm
{
    ...
}

テレメトリ

機能フラグの変更をデプロイするときは、多くの場合、アプリケーションへの影響を分析することが重要です。 たとえば、発生する可能性があるいくつかの質問を次に示します。

  • フラグは、想定どおりに有効または無効になっていますか?
  • 対象ユーザーは、期待どおりに特定の機能にアクセスできていますか?
  • どのバリアントが特定のユーザーに表示されていますか?

機能フラグ評価イベントの出力と分析は、これらの種類の質問に回答するのに役立ちます。 .NET 機能管理ライブラリは、 System.Diagnostics.Activity API を使用して、機能フラグの評価中にトレース テレメトリを生成します。

テレメトリを有効にする

既定では、機能フラグにはテレメトリがありません。 特定の機能フラグのテレメトリを発行するには、フラグでテレメトリの出力が有効になっていることを宣言する 必要があります

appsettings.jsonで定義されている機能フラグの場合は、telemetry プロパティを使用してテレメトリを有効にすることができます。

{
    "feature_management": {
        "feature_flags": [
            {
                "id": "MyFeatureFlag",
                "enabled": true,
                "telemetry": {
                    "enabled": true
                }
            }
        ]
    }
}

appsettings.json ファイルの上記のコードでは、テレメトリが有効になっているMyFeatureFlagという名前の機能フラグが定義されています。 テレメトリの状態は、telemetryenabled に設定するtrue オブジェクトによって示されます。 フラグのテレメトリを発行するには、enabled プロパティの値を true にする必要があります。

機能フラグの telemetry セクションには次のプロパティがあります。

プロパティ 説明
enabled 機能フラグに対してテレメトリを発行するかどうかを指定するブール値。
metadata 機能フラグに関するカスタム メタデータを評価イベントにアタッチするために使用できる、ディクショナリとしてモデル化されたキーと値のペアのコレクション。

カスタム テレメトリの公開

機能マネージャーには、ActivitySourceという名前の独自のMicrosoft.FeatureManagement インスタンスがあります。 機能フラグに対してテレメトリが有効になっている場合:

  • 機能フラグの評価が開始されると、機能マネージャーは Activityのインスタンスを開始します。
  • 機能フラグの評価が完了すると、機能マネージャーは、ActivityEventという名前のFeatureFlagインスタンスを現在のアクティビティに追加します。

FeatureFlag イベントには、機能フラグの評価に関する情報を含むタグがあります。 タグでは 、FeatureEvaluationEvent スキーマで定義されているフィールドが使用されます。

Note

機能フラグの telemetry.metadata プロパティで指定されたすべてのキーと値のペアもタグに含まれます。

カスタム テレメトリの発行を有効にするには、 ActivityListener のインスタンスを作成し、 Microsoft.FeatureManagement アクティビティ ソースをリッスンします。 次のコードは、機能管理アクティビティ ソースをリッスンし、機能が評価されたときにコールバックを追加する方法を示しています。

ActivitySource.AddActivityListener(new ActivityListener()
{
    ShouldListenTo = (activitySource) => activitySource.Name == "Microsoft.FeatureManagement",
    Sample = (ref ActivityCreationOptions<ActivityContext> options) => ActivitySamplingResult.AllData,
    ActivityStopped = (activity) =>
    {
        ActivityEvent? evaluationEvent = activity.Events.FirstOrDefault((activityEvent) => activityEvent.Name == "FeatureFlag");

        if (evaluationEvent.HasValue && evaluationEvent.Value.Tags.Any())
        {
            // Do something.
        }
    }
});

詳細については、「 分散トレースの収集」を参照してください。

Application Insights Telemetry

Microsoft.FeatureManagement.Telemetry.ApplicationInsights パッケージには、Application Insights に機能フラグ評価データを送信する組み込みのテレメトリ パブリッシャーが用意されています。 Microsoft.FeatureManagement.Telemetry.ApplicationInsights パッケージには、イベントをフラグ評価にリンクできるように、すべてのイベントにTargetingIdを自動的にタグ付けするテレメトリ初期化子も用意されています。 この機能を利用するには、パッケージへの参照を追加し、Application Insights テレメトリを登録します。 コードの例は次のとおりです。

builder.services
    .AddFeatureManagement()
    .AddApplicationInsightsTelemetry();

Note

Application Insights テレメトリが期待どおりに動作することを確認するには、 TargetingHttpContextMiddleware クラスを使用する必要があります。

現在のアクティビティでターゲット コンテキストの永続化を有効にするには、 TargetingHttpContextMiddleware クラスを使用できます。

app.UseMiddleware<TargetingHttpContextMiddleware>();

その使用方法の例については、 VariantAndTelemetryDemo の例を参照してください。

前提条件

Microsoft.FeatureManagement.Telemetry.ApplicationInsights パッケージが提供するテレメトリ発行元には、Application Insights をアプリケーション サービスとして設定して登録する必要があります。 サンプル コードについては、 VariantAndTelemetryDemo サンプル アプリケーションを参照してください。

キャッシュ

機能の状態は IConfiguration システムによって提供されます。 構成プロバイダーは、キャッシュと動的更新を処理することが期待されます。 機能マネージャーは、機能が有効かどうかを評価するたびに、機能の状態の最新の値を IConfiguration に求めます。

スナップショット

一部のシナリオでは、要求の有効期間中に機能の状態が一貫している必要があります。 標準の IVariantFeatureManager 実装から返される値は、プル元の IConfiguration ソースが要求中に更新された場合に変更される可能性があります。

この動作は、 IVariantFeatureManagerSnapshotを使用して回避できます。 IVariantFeatureManagerSnapshotと同じ方法でIVariantFeatureManagerを取得できます。 IVariantFeatureManagerSnapshotIVariantFeatureManager インターフェイスを実装しますが、 IVariantFeatureManagerSnapshot は要求中に機能の最初の評価された状態をキャッシュします。 機能の有効期間中にその状態が返されます。

カスタム機能プロバイダー

カスタム機能プロバイダーを実装する場合は、データベースや機能管理サービスなどのソースから機能フラグをプルできます。 既定の機能プロバイダーは、.NET Core 構成システムから機能フラグをプルします。 このシステムは、 appsettings.json ファイルまたは Azure App Configuration などの構成プロバイダーで機能を定義するためのサポートを提供します。 この動作をカスタマイズして、機能定義の読み取り先を制御できます。

機能定義の読み込みをカスタマイズするには、 IFeatureDefinitionProvider インターフェイスを実装する必要があります。

public interface IFeatureDefinitionProvider
{
    Task<FeatureDefinition> GetFeatureDefinitionAsync(string featureName);

    IAsyncEnumerable<FeatureDefinition> GetAllFeatureDefinitionsAsync();
}

IFeatureDefinitionProviderの実装を使用するには、機能管理を追加する前にサービス コレクションに追加する必要があります。 次の例では、InMemoryFeatureDefinitionProvider という名前の IFeatureDefinitionProvider の実装を追加しています。

services.AddSingleton<IFeatureDefinitionProvider, InMemoryFeatureDefinitionProvider>()
        .AddFeatureManagement()

次のステップ

アプリケーションで機能フラグを使用する方法については、次のクイック スタートを参照してください。

機能フィルターの使用方法については、次のチュートリアルを参照してください。