教學課程:在 ASP.NET Core 應用程式中使用功能旗標Tutorial: Use feature flags in an ASP.NET Core app

.NET Core 功能管理程式庫可讓您在 .NET 或 ASP.NET Core 應用程式中以慣用方式實作功能旗標。The .NET Core Feature Management libraries provide idiomatic support for implementing feature flags in a .NET or ASP.NET Core application. 這些程式庫可讓您以宣告方式在程式碼中新增功能旗標,因此您不必以手動方式為功能旗標撰寫所有 if 陳述式。These libraries allow you to declaratively add feature flags to your code so that you don't have to write all the if statements for them manually.

功能管理程式庫也可在幕後管理功能旗標的生命週期。The Feature Management libraries also manage feature flag lifecycles behind the scenes. 例如,這些程式庫會重新整理及快取旗標狀態,或保證旗標的狀態在要求呼叫期間不會變化。For example, the libraries refresh and cache flag states, or guarantee a flag state to be immutable during a request call. 此外,ASP.NET Core 程式庫還提供現成可用的整合,包括 MVC 控制器動作、檢視、路由和中介軟體。In addition, the ASP.NET Core library offers out-of-the-box integrations, including MVC controller actions, views, routes, and middleware.

將功能旗標新增至 ASP.NET Core 應用程式快速入門會示範數種方法,讓您了解如何在 ASP.NET Core 應用程式中新增功能旗標。The Add feature flags to an ASP.NET Core app Quickstart shows several ways to add feature flags in an ASP.NET Core application. 本教學課程會詳細說明這些方法。This tutorial explains these methods in more detail. 如需完整的參考,請參閱 ASP.NET Core 功能管理文件For a complete reference, see the ASP.NET Core feature management documentation.

在本教學課程中,您將學會如何:In this tutorial, you will learn how to:

  • 在應用程式的重要部分新增功能旗標來控制功能的可用性。Add feature flags in key parts of your application to control feature availability.
  • 在您使用應用程式組態來管理功能旗標時與其進行整合。Integrate with App Configuration when you're using it to manage feature flags.

設定功能管理Set up feature management

新增 Microsoft.FeatureManagement.AspNetCoreMicrosoft.FeatureManagement NuGet 套件的參考,以利用 .NET Core 功能管理員。Add a reference to the Microsoft.FeatureManagement.AspNetCore and Microsoft.FeatureManagement NuGet packages to utilize the .NET Core feature manager.

.NET Core 功能管理員 IFeatureManager 會從架構的原生組態系統取得功能旗標。The .NET Core feature manager IFeatureManager gets feature flags from the framework's native configuration system. 因此,您可以使用 .NET Core 所支援的組態來源 (包括本機 appsettings.json 檔或環境變數),來定義應用程式的功能旗標。As a result, you can define your application's feature flags by using any configuration source that .NET Core supports, including the local appsettings.json file or environment variables. IFeatureManager 會仰賴 .NET Core 相依性插入。IFeatureManager relies on .NET Core dependency injection. 您可以使用標準慣例來註冊功能管理服務:You can register the feature management services by using standard conventions:

using Microsoft.FeatureManagement;

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

根據預設,功能管理員會從 .NET Core 組態資料的 "FeatureManagement" 區段擷取功能旗標。By default, the feature manager retrieves feature flags from the "FeatureManagement" section of the .NET Core configuration data. 下列範例會指示功能管理員改為讀取名為 "MyFeatureFlags" 的不同區段:The following example tells the feature manager to read from a different section called "MyFeatureFlags" instead:

using Microsoft.FeatureManagement;

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

如果您在功能旗標中使用篩選條件,則需要納入其他程式庫並予以註冊。If you use filters in your feature flags, you need to include an additional library and register it. 下列範例說明如何使用名為 PercentageFilter 的內建功能篩選條件:The following example shows how to use a built-in feature filter called PercentageFilter:

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

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

建議您將功能旗標置於應用程式外,並個別加以管理。We recommend that you keep feature flags outside the application and manage them separately. 這樣做可讓您隨時修改旗標狀態,並讓那些變更在應用程式中立即生效。Doing so allows you to modify flag states at any time and have those changes take effect in the application right away. 應用程式組態可讓您透過專用的入口網站 UI 在集中的位置組織和控制所有功能旗標。App Configuration provides a centralized place for organizing and controlling all your feature flags through a dedicated portal UI. 應用程式組態也可透過其 .NET Core 用戶端程式庫,直接將旗標傳遞到您的應用程式。App Configuration also delivers the flags to your application directly through its .NET Core client libraries.

若要將 ASP.NET Core 應用程式連線至應用程式組態,最簡單的方式是透過組態提供者 Microsoft.Azure.AppConfiguration.AspNetCoreThe easiest way to connect your ASP.NET Core application to App Configuration is through the configuration provider Microsoft.Azure.AppConfiguration.AspNetCore. 請依照下列步驟來使用此 NuGet 套件。Follow these steps to use this NuGet package.

  1. 開啟 Program.cs 檔案,並新增下列程式碼。Open Program.cs file and add the following code.

    using Microsoft.Extensions.Configuration.AzureAppConfiguration;
    
    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
               .ConfigureAppConfiguration((hostingContext, config) => {
                   var settings = config.Build();
                   config.AddAzureAppConfiguration(options => {
                       options.Connect(settings["ConnectionStrings:AppConfig"])
                              .UseFeatureFlags();
                    });
               })
               .UseStartup<Startup>();
    
  2. 開啟 Startup.cs 並更新 Configure 方法,以新增名為 UseAzureAppConfiguration 的內建中介軟體。Open Startup.cs and update the Configure method to add the built-in middleware called UseAzureAppConfiguration. 此中介軟體可讓功能旗標值依週期性間隔重新整理,同時讓 ASP.NET Core Web 應用程式繼續接收要求。This middleware allows the feature flag values to be refreshed at a recurring interval while the ASP.NET Core web app continues to receive requests.

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        app.UseAzureAppConfiguration();
        app.UseMvc();
    }
    

功能旗標值應該會隨著時間而變更。Feature flag values are expected to change over time. 根據預設,功能旗標值的快取期間為 30 秒,因此在中介軟體接收要求時觸發的重新整理作業,必須要到快取的值過期後才會更新值。By default, the feature flag values are cached for a period of 30 seconds, so a refresh operation triggered when the middleware receives a request would not update the value until the cached value expires. 下列程式碼說明如何透過 options.UseFeatureFlags() 呼叫將快取到期時間或輪詢間隔變更為 5分鐘。The following code shows how to change the cache expiration time or polling interval to 5 minutes in the options.UseFeatureFlags() call.

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

功能旗標宣告Feature flag declaration

每個功能旗標都有兩個部分:名稱以及一份清單,此清單內含可用來評估功能狀態是否為「開啟」 (也就是當其值為 True 時) 的一或多個篩選條件。Each feature flag has two parts: a name and a list of one or more filters that are used to evaluate if a feature's state is on (that is, when its value is True). 篩選條件會定義應開啟功能的使用案例。A filter defines a use case for when a feature should be turned on.

如果功能旗標有多個篩選條件,則會依序周遊篩選條件清單,直到其中一個篩選條件確定應啟用功能。When a feature flag has multiple filters, the filter list is traversed in order until one of the filters determines the feature should be enabled. 屆時,功能旗標即會「開啟」 ,並略過剩餘的篩選結果。At that point, the feature flag is on , and any remaining filter results are skipped. 如果沒有篩選條件指出應啟用功能,則功能旗標會「關閉」 。If no filter indicates the feature should be enabled, the feature flag is off.

功能管理員支援以 appsettings.json 作為功能旗標的組態來源。The feature manager supports appsettings.json as a configuration source for feature flags. 下列範例說明如何在 JSON 檔案中設定功能旗標:The following example shows how to set up feature flags in a JSON file:

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

依照慣例,我們會將此 JSON 文件的 FeatureManagement 區段用於功能旗標設定。By convention, the FeatureManagement section of this JSON document is used for feature flag settings. 上述範例顯示了三個功能旗標,及其在 EnabledFor 屬性中定義的篩選條件:The prior example shows three feature flags with their filters defined in the EnabledFor property:

  • FeatureA 為「開啟」 。FeatureA is on.
  • FeatureB 為「關閉」 。FeatureB is off.
  • FeatureC 會使用 Parameters 屬性指定名為 Percentage 的篩選條件。FeatureC specifies a filter named Percentage with a Parameters property. Percentage 是可設定的篩選條件。Percentage is a configurable filter. 在此範例中,Percentage 會指定 FeatureC 旗標有 50% 的機率會「開啟」 。In this example, Percentage specifies a 50-percent probability for the FeatureC flag to be on.

功能旗標參考Feature flag references

為了能夠輕鬆參考程式碼中的功能旗標,您應將其定義為 enum 變數:So that you can easily reference feature flags in code, you should define them as enum variables:

public enum MyFeatureFlags
{
    FeatureA,
    FeatureB,
    FeatureC
}

功能旗標檢查Feature flag checks

功能管理的基本模式是先檢查功能旗標是否設定為「開啟」 。The basic pattern of feature management is to first check if a feature flag is set to on. 如果是,則功能管理員會功能所包含的動作。If so, the feature manager then runs the actions that the feature contains. 例如:For example:

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

相依性插入Dependency injection

在 ASP.NET Core MVC 中,您可以透過相依性插入來存取功能管理員 IFeatureManagerIn ASP.NET Core MVC, you can access the feature manager IFeatureManager through dependency injection:

public class HomeController : Controller
{
    private readonly IFeatureManager _featureManager;

    public HomeController(IFeatureManager featureManager)
    {
        _featureManager = featureManager;
    }
}

控制器動作Controller actions

在 MVC 控制器中,您可以使用 FeatureGate 屬性來控制是要啟用整個控制器類別還是特定動作。In MVC controllers, you use the FeatureGate attribute to control whether a whole controller class or a specific action is enabled. 下列 HomeController 控制器必須在 FeatureA「開啟」 時,才能執行該控制器類別所包含的動作:The following HomeController controller requires FeatureA to be on before any action the controller class contains can be executed:

using Microsoft.FeatureManagement.Mvc;

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

下列 Index 動作必須在 FeatureA「開啟」 時才能執行:The following Index action requires FeatureA to be on before it can run:

using Microsoft.FeatureManagement.Mvc;

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

當 MVC 控制器或動作因為控制功能旗標「關閉」 而遭到封鎖時,系統便會呼叫已註冊的 IDisabledFeaturesHandler 介面。When an MVC controller or action is blocked because the controlling feature flag is off , a registered IDisabledFeaturesHandler interface is called. 預設的 IDisabledFeaturesHandler 介面會對用戶端傳回沒有回應本文的 404 狀態碼。The default IDisabledFeaturesHandler interface returns a 404 status code to the client with no response body.

MVC 檢視MVC views

Views 目錄中開啟 _ViewImports.cshtml ,並新增功能管理員標記協助程式:Open _ViewImports.cshtml in the Views directory, and add the feature manager tag helper:

@addTagHelper *, Microsoft.FeatureManagement.AspNetCore

在 MVC 檢視中,您可以使用 <feature> 標記,根據功能旗標是否已啟用來呈現內容:In MVC views, you can use a <feature> tag to render content based on whether a feature flag is enabled:

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

若要在不符合需求時顯示替代內容,可以使用 negate 屬性。To display alternate content when the requirements are not met the negate attribute can be used.

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

如果清單中的任何功能或所有功能都啟用,功能 <feature> 標記也可以用來顯示內容。The feature <feature> tag can also be used to show content if any or all features in a list are enabled.

<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 filters

您可以將 MVC 篩選條件設定為根據功能旗標的狀態來啟用。You can set up MVC filters so that they're activated based on the state of a feature flag. 下列程式碼會新增名為 SomeMvcFilter 的 MVC 篩選條件。The following code adds an MVC filter named SomeMvcFilter. 只有在 FeatureA 已啟用時,才會在 MVC 管線內觸發此篩選條件。This filter is triggered within the MVC pipeline only if FeatureA is enabled. 這項功能受限於 IAsyncActionFilterThis capability is limited to IAsyncActionFilter.

using Microsoft.FeatureManagement.FeatureFilters;

IConfiguration Configuration { get; set;}

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

中介軟體Middleware

您也可以使用功能旗標,根據條件新增應用程式分支和中介軟體。You can also use feature flags to conditionally add application branches and middleware. 下列程式碼只有在 FeatureA 啟用時,才會在要求管線中插入中介軟體元件:The following code inserts a middleware component in the request pipeline only when FeatureA is enabled:

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

此程式碼會建置更泛型的功能,以根據功能旗標為整個應用程式建立分支:This code builds off the more-generic capability to branch the entire application based on a feature flag:

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

後續步驟Next steps

在本教學課程中,您已了解如何藉由使用 Microsoft.FeatureManagement 程式庫在 ASP.NET Core 應用程式中實作功能旗標。In this tutorial, you learned how to implement feature flags in your ASP.NET Core application by using the Microsoft.FeatureManagement libraries. 若要進一步了解 ASP.NET Core 和應用程式組態中的功能管理支援,請參閱下列資源:For more information about feature management support in ASP.NET Core and App Configuration, see the following resources: