チュートリアル: ASP.NET Core アプリケーションで対象ユーザーに対して機能をロールアウトする

このチュートリアルでは、ターゲット フィルターを使用して、ASP.NET Core アプリケーションの対象ユーザーに機能をロールアウトします。 ターゲット フィルターの詳細については、「対象ユーザーに対して機能をロールアウトする」を参照してください。

前提条件

機能フラグを使用する Web アプリケーションを作成する

このセクションでは、ユーザーがサインインし、前に作成された Beta 機能フラグを使用できるようにする Web アプリケーションを作成します。

  1. 次のコマンドを使用して、ローカル データベースに対して認証を行う Web アプリケーションを作成します。

    dotnet new webapp --auth Individual -o TestFeatureFlags
    
  2. 次の NuGet パッケージへの参照を追加します。

    dotnet add package Microsoft.Azure.AppConfiguration.AspNetCore
    dotnet add package Microsoft.FeatureManagement.AspNetCore
    
  3. App Configuration ストアの接続文字列を格納します。

    dotnet user-secrets init
    dotnet user-secrets set ConnectionStrings:AppConfig "<your_connection_string>"
    
  4. Azure App Configuration と機能管理をアプリケーションに追加します。

    次のコードで Program.cs ファイルを更新します。

    // Existing code in Program.cs
    // ... ...
    
    var builder = WebApplication.CreateBuilder(args);
    
    // Retrieve the App Config connection string
    string AppConfigConnectionString = builder.Configuration.GetConnectionString("AppConfig") ?? throw new InvalidOperationException("Connection string 'AppConfig' not found."); ;
    
    // Load feature flag configuration from Azure App Configuration
    builder.Configuration.AddAzureAppConfiguration(options =>
    {
        options.Connect(AppConfigConnectionString);
        options.UseFeatureFlags();
    });
    
    // Add Azure App Configuration middleware to the container of services
    builder.Services.AddAzureAppConfiguration();
    
    // Add feature management to the container of services
    builder.Services.AddFeatureManagement();
    
    // The rest of existing code in Program.cs
    // ... ...
    
  5. App Configuration ミドルウェアを使用して、Azure App Configuration からの構成と機能フラグ更新を有効にします。

    次のコードを使用して Program.cs を更新します。

    // Existing code in Program.cs
    // ... ...
    
    var app = builder.Build();
    
    // Use Azure App Configuration middleware for dynamic configuration refresh
    app.UseAzureAppConfiguration();
    
    // The rest of existing code in Program.cs
    // ... ...
    
  6. Pages ディレクトリの下に Beta という名前の新しい空の Razor ページを追加します。 これには、"Beta.cshtml" と "Beta.cshtml.cs" の 2 つのファイルが含まれています。

    @page
    @model TestFeatureFlags.Pages.BetaModel
    @{
        ViewData["Title"] = "Beta Page";
    }
    
    <h1>This is the beta website.</h1>
    
  7. "Beta.cshtml.cs" を開き、BetaModel クラスに FeatureGate 属性を追加します。

    using Microsoft.AspNetCore.Mvc.RazorPages;
    using Microsoft.FeatureManagement.Mvc;
    
    namespace TestFeatureFlags.Pages
    {
        [FeatureGate("Beta")]
        public class BetaModel : PageModel
        {
            public void OnGet()
            {
            }
        }
    }
    
  8. Pages/_ViewImports.cshtml を開き、@addTagHelper ディレクティブを使用して機能マネージャーのタグ ヘルパーを登録します。

    @addTagHelper *, Microsoft.FeatureManagement.AspNetCore
    
  9. Pages/Shared ディレクトリの _Layout.cshtml を開きます。 次の強調表示されている行に示すように、HomePrivacy navbar 項目の間に新しい <feature> タグを挿入します。

    <nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
        <div class="container">
            <a class="navbar-brand" asp-area="" asp-page="/Index">TestAppConfigNet3</a>
            <button class="navbar-toggler" type="button" data-toggle="collapse" data-target=".navbar-collapse" aria-controls="navbarSupportedContent"
                    aria-expanded="false" aria-label="Toggle navigation">
                <span class="navbar-toggler-icon"></span>
            </button>
            <div class="navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse">
                <ul class="navbar-nav flex-grow-1">
                    <li class="nav-item">
                        <a class="nav-link text-dark" asp-area="" asp-page="/Index">Home</a>
                    </li>
                    <feature name="Beta">
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-page="/Beta">Beta</a>
                        </li>
                    </feature>
                    <li class="nav-item">
                        <a class="nav-link text-dark" asp-area="" asp-page="/Privacy">Privacy</a>
                    </li>
                </ul>
            </div>
        </div>
    </nav>
    

Web アプリケーションのターゲット設定を有効にする

ターゲット フィルターは、ユーザー ID とユーザーが属するグループで構成されるユーザーのターゲット コンテキストに基づいて、ユーザーの機能の状態を評価します。 この例では、サインイン ユーザーのメール アドレスをユーザー ID として使用し、メール アドレスのドメイン名をグループとして使用しています。

  1. ExampleTargetingContextAccessor.cs ファイルに次のコードを追加します。 ITargetingContextAccessor インターフェイスを実装して、現在の要求のサインイン ユーザーのターゲット コンテキストを提供します。

    using Microsoft.FeatureManagement.FeatureFilters;
    
    namespace TestFeatureFlags
    {
        public class ExampleTargetingContextAccessor : ITargetingContextAccessor
        {
            private const string TargetingContextLookup = "ExampleTargetingContextAccessor.TargetingContext";
            private readonly IHttpContextAccessor _httpContextAccessor;
    
            public ExampleTargetingContextAccessor(IHttpContextAccessor httpContextAccessor)
            {
                _httpContextAccessor = httpContextAccessor ?? throw new ArgumentNullException(nameof(httpContextAccessor));
            }
    
            public ValueTask<TargetingContext> GetContextAsync()
            {
                HttpContext httpContext = _httpContextAccessor.HttpContext;
                if (httpContext.Items.TryGetValue(TargetingContextLookup, out object value))
                {
                    return new ValueTask<TargetingContext>((TargetingContext)value);
                }
                List<string> groups = new List<string>();
                if (httpContext.User.Identity.Name != null)
                {
                    groups.Add(httpContext.User.Identity.Name.Split("@", StringSplitOptions.None)[1]);
                }
                TargetingContext targetingContext = new TargetingContext
                {
                    UserId = httpContext.User.Identity.Name,
                    Groups = groups
                };
                httpContext.Items[TargetingContextLookup] = targetingContext;
                return new ValueTask<TargetingContext>(targetingContext);
            }
        }
    }
    
  2. Program.cs ファイルを開き、WithTargeting メソッドを呼び出してターゲット フィルターを有効にします。 機能フラグの評価中にターゲット フィルターがターゲット コンテキストを取得するために使用する型 ExampleTargetingContextAccessor を渡します。 HttpContextAccessor をサービス コレクションに追加して、ExampleTargetingContextAccessorHttpContext から、サインインしているユーザーの情報にアクセスできるようにします。

    // Existing code in Program.cs
    // ... ...
    
    // Add feature management to the container of services
    builder.Services.AddFeatureManagement()
                    .WithTargeting<ExampleTargetingContextAccessor>();
    
    // Add HttpContextAccessor to the container of services.
    builder.Services.AddHttpContextAccessor();
    
    // The rest of existing code in Program.cs
    // ... ...
    

    Note

    Blazor アプリケーションの場合は、機能管理をスコープ付きサービスとして有効にする方法をご覧ください。

ターゲット フィルターの動作

  1. アプリケーションをビルドして実行します。 [既定のパーセンテージ] オプションが 0 に設定されているため、初期状態では [Beta] 項目はツールバーに表示されません。

    ユーザーがログインしておらず、Beta 項目が表示されていない

  2. 右上隅にある [登録] リンクを選択して、新しいユーザー アカウントを作成します。 test@contoso.com のメール アドレスを使用します。 [Register Confirmation]\(登録の確認\) 画面で、 [Click here to confirm your account]\(ここをクリックしてアカウントを確認\) を選択します。

  3. アカウント登録時に設定したパスワードを使用して test@contoso.com としてサインインします。

    test@contoso.com がターゲット ユーザーとして指定されているため、 [Beta] 項目がツールバーに表示されるようになりました。

    ユーザーがログインして Beta 項目が表示される

    次に、アカウント登録時に設定したパスワードを使用して testuser@contoso.com としてサインインします。 "ベータ版" の項目は、ツール バーには表示されません。これは、testuser@contoso.com が除外ユーザーとして指定されているためです。

    @contoso.com@contoso-xyz.com のメール アドレスを使用して追加のユーザーを作成し、グループ設定の動作を確認できます。

    contoso-xyz.com のメール アドレスを持つユーザーには、"ベータ版" アイテムは表示されません。 @contoso.com のメール アドレスを持つユーザーの 50% には "ベータ版" アイテムが表示されますが、残りの 50% には "ベータ版" アイテムは表示されません。

次のステップ

機能フィルターについてさらに学ぶには、次のチュートリアルに進んでください。

.NET 機能管理ライブラリの完全な機能の概要については、次のドキュメントに進んでください。