教學課程:在 ASP.NET Core 應用程式中使用功能旗標

.NET Core 功能管理程式庫可讓您在 .NET 或 ASP.NET Core 應用程式中以慣用方式實作功能旗標。 這些程式庫讓您以宣告方式新增功能旗標至程式碼,所以您不必手動撰寫程式碼啟用或停用包含 if 陳述式的功能。

功能管理程式庫也可在幕後管理功能旗標的生命週期。 例如,這些程式庫會重新整理及快取旗標狀態,或保證旗標的狀態在要求呼叫期間不會變化。 此外,ASP.NET Core 程式庫還提供現成可用的整合,包括 MVC 控制器動作、檢視、路由和中介軟體。

新增功能旗標至 ASP.NET Core 應用程式快速入門示範如何在 ASP.NET Core 應用程式中使用功能旗標的簡單範例。 本教學課程示範功能管理程式庫的其他設定選項和功能。 您可以使用在快速入門中建立的範例應用程式,以試用在本教學課程中顯示的範例程式碼。

如需 ASP.NET Core 功能管理 API 參考文件,請參閱 Microsoft.FeatureManagement 命名空間

在本教學課程中,您將學會如何:

  • 在應用程式的重要部分新增功能旗標來控制功能的可用性。
  • 在您使用應用程式組態來管理功能旗標時與其進行整合。

設定功能管理

若要存取 .NET Core 功能管理員,您的應用程式必須包含 Microsoft.FeatureManagement.AspNetCore NuGet 套件的參考。

.NET Core 功能管理員是由架構的原生設定系統所設定。 因此,您可以使用 .NET Core 支援的設定來源 (包括本機 appsettings.json 檔案或環境變數),定義應用程式的功能旗標設定。

根據預設,功能管理員會從 .NET Core 設定資料的 "FeatureManagement" 區段來擷取功能旗標設定。 若要使用預設設定位置,請呼叫傳遞至啟動類別 ConfigureServices 方法中,IServiceCollectionAddFeatureManagement 方法。

using Microsoft.FeatureManagement;

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

您可以呼叫 Configuration.GetSection 並傳入所需區段的名稱,然後指定從不同的設定區段擷取功能管理設定。 下列範例會指示功能管理員改為讀取名為 "MyFeatureFlags" 的不同區段:

using Microsoft.FeatureManagement;

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        ...
        services.AddFeatureManagement(Configuration.GetSection("MyFeatureFlags"));
    }
}

如果您在功能旗標中使用篩選,請務必包含 Microsoft.FeatureManagement.FeatureFilters 命名空間並新增對 AddFeatureFilters 的呼叫,指定您要作為方法泛型型別的篩選類型名稱。 如需使用功能篩選動態啟用或停用功能的詳細資訊,請參閱針對目標對象啟用分段推出功能

下列範例說明如何使用名為 PercentageFilter 的內建功能篩選條件:

using Microsoft.FeatureManagement;
using Microsoft.FeatureManagement.FeatureFilters;

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        ...
        services.AddFeatureManagement()
                .AddFeatureFilter<PercentageFilter>();
    }
}

建議您不要將功能旗標程式碼寫入應用程式,而是將其保留在應用程式外部並個別管理。 這樣做可讓您隨時修改旗標狀態,並讓那些變更在應用程式中立即生效。 Azure 應用程式設定服務提供用於管理所有功能旗標的專用入口網站 UI。 Azure 應用程式設定服務也可透過 .NET Core 用戶端程式庫,直接傳遞功能旗標至應用程式。

若要連線 ASP.NET Core 應用程式與應用程式設定,最簡單的方式是透過 Microsoft.Azure.AppConfiguration.AspNetCore NuGet 套件包含的設定提供者。 包含套件的參考後,請遵循下列步驟使用此 NuGet 套件。

  1. 開啟 Program.cs 檔案,並新增下列程式碼。

    重要事項

    CreateHostBuilder 會取代 .NET Core 3.x 中的 CreateWebHostBuilder。 根據您的環境選取正確的語法。

    using Microsoft.Extensions.Configuration.AzureAppConfiguration;
    
    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
                webBuilder.ConfigureAppConfiguration(config =>
                {
                    var settings = config.Build();
                    config.AddAzureAppConfiguration(options =>
                        options.Connect(settings["ConnectionStrings:AppConfig"]).UseFeatureFlags());
                }).UseStartup<Startup>());
    
  2. 開啟 Startup.cs 並更新 ConfigureConfigureServices 方法,新增名為 UseAzureAppConfiguration 的內建中介軟體。 此中介軟體可讓功能旗標值依週期性間隔重新整理,同時讓 ASP.NET Core Web 應用程式繼續接收要求。

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        app.UseAzureAppConfiguration();
    }
    
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddAzureAppConfiguration();
    }
    

在典型案例中,部署並啟用應用程式的不同功能後,功能旗標值會定期更新。 根據預設,功能旗標值的快取期間為 30 秒,因此在中介軟體接收要求時觸發的重新整理作業,必須要到快取的值過期後才會更新值。 下列程式碼說明如何在呼叫 UseFeatureFlags 時,設定 CacheExpirationInterval,並將快取到期時間或輪詢間隔變更為 5分鐘。

config.AddAzureAppConfiguration(options =>
    options.Connect(settings["ConnectionStrings:AppConfig"]).UseFeatureFlags(featureFlagOptions => {
        featureFlagOptions.CacheExpirationInterval = TimeSpan.FromMinutes(5);
    }));
});

功能旗標宣告

每個功能旗標宣告都有兩個部分:名稱和一或多個篩選條件的清單,而此清單用來評估功能狀態是否為「開啟」(亦即狀態值為 True 時)。 篩選條件定義開啟功能時機的準則。

如果功能旗標有多個篩選條件,則會依序周遊篩選條件清單,直到其中一個篩選條件確定應啟用功能。 屆時,功能旗標即會「開啟」 ,並略過剩餘的篩選結果。 如果沒有篩選條件指出應啟用功能,則功能旗標會「關閉」 。

功能管理員支援以 appsettings.json 作為功能旗標的組態來源。 下列範例說明如何在 JSON 檔案中設定功能旗標:

{"FeatureManagement": {
        "FeatureA": true, // Feature flag set to on
        "FeatureB": false, // Feature flag set to off
        "FeatureC": {
            "EnabledFor": [
                {
                    "Name": "Percentage",
                    "Parameters": {
                        "Value": 50
                    }
                }
            ]
        }
    }
}

依照慣例,我們會將此 JSON 文件的 FeatureManagement 區段用於功能旗標設定。 上述範例顯示了三個功能旗標,及其在 EnabledFor 屬性中定義的篩選條件:

  • FeatureA 為「開啟」 。
  • FeatureB 為「關閉」 。
  • FeatureC 會使用 Parameters 屬性指定名為 Percentage 的篩選條件。 Percentage 是可設定的篩選條件。 在此範例中,Percentage 會指定 FeatureC 旗標有 50% 的機率會「開啟」 。 如需使用功能篩選的操作指南,請參閱使用功能篩選啟用條件式功能旗標

使用相依性插入存取 IFeatureManager

如果是手動檢查功能旗標值等作業,請取得 IFeatureManager 的執行個體。 在 ASP.NET Core MVC 中,您可以透過相依性插入存取功能管理員 IFeatureManager。 在下列範例中,IFeatureManager 類型的引數會新增至控制器的建構函式簽章。 呼叫建構函式時,執行階段會自動解析參考並提供介面。 如果您目前使用的應用程式範本中的控制器,在建構函式已有一或多個相依性插入引數 (例如 ILogger),您可以直接新增 IFeatureManager 作為其他引數:

using Microsoft.FeatureManagement;

public class HomeController : Controller
{
    private readonly IFeatureManager _featureManager;

    public HomeController(ILogger<HomeController> logger, IFeatureManager featureManager)
    {
        _featureManager = featureManager;
    }
}

功能旗標參考

若要從程式碼參考功能旗標,請將功能旗標定義為字串變數:

public static class MyFeatureFlags
{
    public const string FeatureA = "FeatureA";
    public const string FeatureB = "FeatureB";
    public const string FeatureC = "FeatureC";
}

功能旗標檢查

功能管理的常見模式是,檢查功能旗標是否設為「開啟」,如果是,請執行一段程式碼。 例如:

IFeatureManager featureManager;
...
if (await featureManager.IsEnabledAsync(MyFeatureFlags.FeatureA))
{
    // Run the following code
}

控制器動作

使用 MVC 控制器時,您可以使用 FeatureGate 屬性,控制是否啟用整個控制器類別或特定動作。 下列 HomeController 控制器必須在 FeatureA「開啟」 時,才能執行該控制器類別所包含的動作:

using Microsoft.FeatureManagement.Mvc;

[FeatureGate(MyFeatureFlags.FeatureA)]
public class HomeController : Controller
{
    ...
}

下列 Index 動作必須在 FeatureA「開啟」 時才能執行:

using Microsoft.FeatureManagement.Mvc;

[FeatureGate(MyFeatureFlags.FeatureA)]
public IActionResult Index()
{
    return View();
}

因為控制功能旗標「關閉」而封鎖 MVC 控制器或動作時,系統便會呼叫註冊的 IDisabledFeaturesHandler 介面。 預設的 IDisabledFeaturesHandler 介面會對用戶端傳回沒有回應本文的 404 狀態碼。

MVC 檢視

Views 目錄中開啟 _ViewImports.cshtml ,並新增功能管理員標記協助程式:

@addTagHelper *, Microsoft.FeatureManagement.AspNetCore

在 MVC 檢視中,您可以使用 <feature> 標記,根據功能旗標是否已啟用來呈現內容:

<feature name="FeatureA">
    <p>This can only be seen if 'FeatureA' is enabled.</p>
</feature>

若要在不符合需求時顯示替代內容,可以使用 negate 屬性。

<feature name="FeatureA" negate="true">
    <p>This will be shown if 'FeatureA' is disabled.</p>
</feature>

如果清單中的任何功能或所有功能都啟用,功能 <feature> 標記也可以用來顯示內容。

<feature name="FeatureA, FeatureB" requirement="All">
    <p>This can only be seen if 'FeatureA' and 'FeatureB' are enabled.</p>
</feature>
<feature name="FeatureA, FeatureB" requirement="Any">
    <p>This can be seen if 'FeatureA', 'FeatureB', or both are enabled.</p>
</feature>

MVC 篩選條件

您可以將 MVC 篩選條件設定為根據功能旗標的狀態來啟用。 此功能限於實作 IAsyncActionFilter 的篩選。 下列程式碼會新增名為 ThirdPartyActionFilter 的 MVC 篩選條件。 只有在 FeatureA 已啟用時,才會在 MVC 管線內觸發此篩選條件。

using Microsoft.FeatureManagement.FeatureFilters;

IConfiguration Configuration { get; set;}

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc(options => {
        options.Filters.AddForFeature<ThirdPartyActionFilter>(MyFeatureFlags.FeatureA);
    });
}

中介軟體

您也可以使用功能旗標,根據條件新增應用程式分支和中介軟體。 下列程式碼只有在 FeatureA 啟用時,才會在要求管線中插入中介軟體元件:

app.UseMiddlewareForFeature<ThirdPartyMiddleware>(MyFeatureFlags.FeatureA);

此程式碼會建置更泛型的功能,以根據功能旗標為整個應用程式建立分支:

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

後續步驟

在本教學課程中,您已了解如何藉由使用 Microsoft.FeatureManagement 程式庫在 ASP.NET Core 應用程式中實作功能旗標。 若要進一步了解 ASP.NET Core 和應用程式組態中的功能管理支援,請參閱下列資源: