共用方式為


.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 應用程式組態的各種案例。

功能旗標宣告

功能管理程式庫支援 appsettings.json 組態檔做為功能旗標來源,因為它是 .NET Core IConfiguration 系統的提供者。 功能標記是使用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"
                            }
                        }
                    ]
                }
            }
        ]
    }
}

feature_management JSON 文件的區段會依慣例來載入功能旗標設定。 您必須在本節中列出陣列中的 feature_flags 功能旗標物件。 此程式碼列出了三個功能標誌。 每個功能旗標物件都有一個 id 和一個 enabled 屬性。

  • id 值是您用來識別和參考功能旗標的名稱。
  • enabled 屬性會指定功能旗標的啟用狀態。

如果 enabledfalse,則功能關閉。 如果是 enabled,則true功能的狀態取決於conditions屬性。 屬性 conditions 會宣告用來動態啟用功能的條件。

  • 如果功能旗標沒有 conditions 屬性,則該功能已開啟。
  • 如果功能旗標具有 conditions 屬性,且符合其條件,則該功能會開啟。
  • 如果功能旗標具有 conditions 屬性,且不符合其條件,則該功能會關閉。

功能篩選器定義在陣列中 client_filters 。 在上述程式碼中, FeatureV 功能旗標具有名為 Microsoft.TimeWindow的功能篩選器。 此篩選是可設定的功能篩選範例。 在此程式碼中,此篩選條件具有屬性 parameters 。 此屬性可用來設定篩選。 在此情況下,會設定要成為作用中功能的開始和結束時間。

進階: 冒號字元 (:) 禁止在功能旗標名稱中使用。

需求類型

在屬性內 conditions ,屬性 requirement_type 可用來判斷篩選器在評估功能狀態時是否應該使用 AnyAll 邏輯。 如果未指定 requirement_type,則預設值為 Any。 這些 requirement_type 值會產生下列行為:

  • Any:只需一個篩選器滿足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 一節)。 當相同的功能旗標識別碼出現在多個組態來源中時,內建 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 功能管理架構不支援新功能,包括變體和遙測。

附註

如果功能旗標設定中同時在feature_managementFeatureManagement區段列出相同的宣告,則會採用feature_management區段中的宣告。

使用量

在基本實作中,功能管理會檢查是否已啟用功能旗標。 然後它根據結果執行操作。 此檢查是透過 IVariantFeatureManagerIsEnabledAsync 方法進行。

…
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功能旗標組態。 如果這兩個區段都不存在,則配置會被視為空。

附註

您也可以指定應將功能旗標組態從不同的組態區段擷取,方法是將區段傳遞至 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 控制器和動作可能需要啟用指定的功能或任何功能清單之一,才能執行。 您可以使用 FeatureGateAttribute 物件來滿足此需求。 FeatureGateAttribute 類別定義在 Microsoft.FeatureManagement.Mvc 命名空間中。

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

在上述範例中, HomeController 類別是由 FeatureX控制。 HomeController 只有在啟用此功能 FeatureX 時,動作才能執行。

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

在上述範例中, Index 只有在啟用此功能 FeatureX 時,MVC 動作才能執行。

已停用的動作處理

當 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> 標籤來參照多個變體。 若要這樣做,請在requirement屬性中使用Any值,並在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>

附註

  • 如果您指定變體,則應僅指定 一個 特徵。
  • 如果您指定多個變體並使用 And 作為 requirement 值,則會擲回錯誤。 您無法分配多個變體。

<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 頁面可能需要啟用指定的功能或任何功能清單之一,才能執行。 您可以透過使用 FeatureGateAttribute 物件來新增此需求。 FeatureGateAttribute 類別定義在 Microsoft.FeatureManagement.Mvc 命名空間中。

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

這段程式碼會設定一個 Razor 頁面,該頁面需要啟用 FeatureX。 如果未啟用此功能,頁面會產生 HTTP 404 (NotFound) 結果。

當您在 Razor 頁面上使用 FeatureGateAttribute 物件時,必須將 FeatureGateAttribute 應用於頁面處理常式的類型上。 您無法將它放在個別處理常式方法上。

應用程式建置

您可以使用功能管理程式庫來新增應用程式分支和中介軟體,這些分支和中介軟體會根據功能的狀態以條件式執行。

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

在上述程式碼中,應用程式只會在啟用功能 FeatureX 時,才會新增中介軟體元件,該元件才會出現在要求管線中。 如果在運行時間期間啟用或停用該功能,則可以動態變更中介軟體管線。

如下列程式碼所示,此功能建置在更一般的功能之上,可根據功能分支整個應用程式。

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

實作功能篩選

建立功能篩選可讓您根據您定義的準則來啟用功能。 若要實作功能篩選器,您必須實作 IFeatureFilter 介面。 IFeatureFilter 具有名為 EvaluateAsync 的單一方法。 當功能指定其可以針對功能篩選啟用時,就會呼叫 EvaluateAsync 方法。 如果EvaluateAsync返回true,則應啟用該功能。

下列程式碼示範如何新增名為 MyCriteriaFilter的自訂功能篩選器。

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

您可以在 AddFeatureManagement 傳回的 IFeatureManagementBuilder 實作上呼叫 AddFeatureFilter<T>,註冊功能篩選。 功能篩選器可以存取您用來新增功能旗標的服務集合中的服務。 您可以使用相依性插入來擷取這些服務。

附註

當您在功能旗標設定中參考篩選器時(例如,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 尾碼的功能篩選類型名稱,如果有的話會移除。 例如,您應該在配置中將 MyCriteriaFilter 參照為 MyCriteria

{
    "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();
    …
}

進階:IHttpContextAccessorHttpContext 不應該用於伺服器端 Blazor 應用程式的 Razor 元件。 在 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> 時利用所傳入的上下文。 TContext中的IContextualFeatureFilter<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

附註

單一功能篩選介面只能由單一類型實作。 嘗試新增實作多個功能篩選介面的功能篩選會導致 ArgumentException 例外狀況。

使用相同的別名使用內容相關和非內容相關的篩選

實作 IFeatureFilterIContextualFeatureFilter 的篩選器可以共用相同的別名。 具體來說,如果最多有一個適用的 ContextType 篩選,您可以讓零個或一個 IFeatureFilter 實作和零個或 NIContextualFeatureFilter<ContextType> 個實作共用一個篩選別名。

若要瞭解在應用程式中註冊相同名稱的內容和非內容過濾器時選取過濾器的程序,請考慮下列範例。

三個篩選器共用 SharedFilterName 別名:

  • 一個名為 FilterA 的非語境性篩選器
  • 接受 TypeB 上下文的名為 FilterB 的上下文篩選器
  • 名為 FilterC 的內容篩選,可接受 TypeC 內容

稱為MyFeatureSharedFilterName的功能旗標會在其組態中使用功能篩選器。

如果所有三個過濾器都已註冊:

  • 當您呼叫 IsEnabledAsync("MyFeature")時,篩選器 FilterA 會用來評估功能旗標。
  • 當您使用IsEnabledAsync("MyFeature", context)撥打電話時:
    • 如果類型contextTypeB,則使用 。 FilterB
    • 如果類型contextTypeC,則使用 。 FilterC
    • 如果類型contextTypeF,則使用 。 FilterA

內建功能篩選

套件 Microsoft.FeatureManagement 附帶部分功能篩選器:PercentageFilterTimeWindowFilterContextualTargetingFilterTargetingFilter。 當您使用 AddFeatureManagement 方法註冊功能管理時,TargetingFilter 除外的所有篩選會自動新增。 TargetingFilter 是使用方法 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"
                }
            }
        ]
    }
}

您可以將篩選器設定為定期套用時間範圍。 當您需要在一天或一週的特定日子的低流量或高流量期間開啟功能時,此功能會很有用。 若要將個別時間範圍擴充為週期性時間範圍,您可以使用 Recurrence 參數來指定週期性規則。

附註

若要使用週期性,您必須指定 StartEnd 值。 使用定期模式時,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 由兩部分組成:

  • 這些 Pattern 設定會指定時間範圍重複的頻率。
  • 這些 Range 設定會指定週期性模式重複的時間長度。

定期模式

有兩種可能的定期模式類型:DailyWeekly。 例如,時間範圍可以每天、每三天、每週一或每隔一個星期五重複一次。

視類型而定,設定的 Pattern 某些欄位為必填、選用或忽略。

  • Daily

    每日週期模式會導致時間範圍根據每次出現之間的指定天數重複。

    屬性 相關性 描述
    Type 必要 週期性模式類型。 必須設為 Daily
    Interval 選用 每次出現之間的天數。 預設值是 1
  • Weekly

    每週週期模式會導致時間範圍在一週中的同一天或幾天重複。 但您可以指定每組出現項目之間的週數。

    屬性 相關性 描述
    Type 必要 週期性模式類型。 必須設為 Weekly
    DaysOfWeek 必要 事件發生的星期幾。
    Interval 選用 每組事件發生之間的週數。 預設值是 1
    FirstDayOfWeek 選用 用來作為一週第一天的日期。 預設值是 Sunday

    下列範例每隔一個星期一和星期二重複時間範圍:

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

附註

Start 值必須是符合週期性模式的有效第一次出現項目。 此外,時間範圍的持續時間不能超過其發生頻率。 例如,25 小時的時間範圍不能每天重複。

定期範圍

有三種可能的週期範圍類型: NoEndEndDateNumbered

  • 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 必要 出現次數。

    在下列範例中,時間範圍會在星期一和星期二重複,總共發生三次,發生在下列日期:

    • 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 底下列出它們的名稱。
    • Exclusion 區段的 Groups 底下列出它們所屬的群組。
  • 如果未排除使用者,則在符合下列任何條件時啟用此功能:

    • 使用者會列在區段 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

目標

指定目標是一種功能管理策略,您可以使用它逐步向使用者群推出新功能。 此策略是建立在以一組稱為目標「對象」的使用者為目標的概念之上。 目標對象由特定使用者、群組、排除的使用者和群組,以及整個使用者群的指定百分比所組成。 對象中包含的群組可以進一步細分為其成員總數的百分比。

下列步驟示範名為 Beta 版的新功能漸進式推出範例:

  1. 個人用戶 Jeff 和 Alicia 被授予訪問 Beta 功能的權限。
  2. 另一位使用者 Mark 要求加入並包含在內。
  3. Ring1 組中 20% 的用戶包含在 Beta 功能中。
  4. 包含的 Ring1 用戶數量增加到 100%。
  5. 百分之五的用戶群包含在 Beta 功能中。
  6. 推出百分比會提高到 100%,以完全推出該功能。

程式庫支援此策略,透過內建的 Microsoft.Targeting 功能篩選推出功能。

在 Web 應用程式中鎖定目標

如需使用目標功能篩選器的 Web 應用程式範例,請參閱 FeatureFlagDemo 範例專案。

若要開始在 TargetingFilter 應用程式中使用,您必須將它新增至應用程式的服務集合,就像任何其他功能篩選器一樣。 與其他內建篩選器不同, TargetingFilter 依賴另一個服務來新增至應用程式的服務集合。 該服務是一種 ITargetingContextAccessor 實現。

程式Microsoft.FeatureManagement.AspNetCore庫提供預設實作ITargetingContextAccessor,可從請求值HttpContext擷取目標資訊。 您可以在使用 IFeatureManagementBuilder 上的非泛型 WithTargeting 多載設定目標時,使用預設目標內容存取子。

若要註冊預設目標內容存取子和 TargetingFilter,您可以在 IFeatureManagementBuilder 上呼叫 WithTargeting

services.AddFeatureManagement()
        .WithTargeting();

您也可藉由呼叫 WithTargeting<T> 來註冊 ITargetingContextAccessorTargetingFilter 的自訂實作。 下列程式碼會在 Web 應用程式中設定功能管理,以搭配稱為 ExampleTargetingContextAccessorITargetingContextAccessor 實作使用 TargetingFilter

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

ITargetingContextAccessor

若要在 Web 應用程式中使用TargetingFilter,需要實作ITargetingContextAccessor。 這項需求背後的原因是,目標評估需要內容資訊,例如使用者的相關資訊。 此資訊儲存在類別的 TargetingContext 實例中。 不同的應用程式會從不同位置擷取此資訊,例如請求的 HTTP 內容或資料庫。

如需從應用程式的 HTTP 內容擷取目標內容資訊的範例,請參閱 DefaultHttpTargetingContextAccessor 套件中 Microsoft.FeatureManagement.AspNetCore 。 它會擷取下列資訊:

  • 來自HttpContext.User屬性的目標資訊
  • UserId 來自 Identity.Name 欄位的信息
  • Role 類型宣告中的 Groups 資訊

此實作依賴於使用 IHttpContextAccessor. 如需更多關於IHttpContextAccessor的詳細資訊,請參閱本文稍早的HttpContext使用說明。

主控台應用程式中的目標設置

目標篩選條件依賴於目標內容來評估是否應該開啟功能。 此目標內容包含正在評估的使用者和使用者所屬的群組等資訊。 在主控台應用程式中,通常沒有環境內容可用來將這項資訊傳遞至目標篩選器。 因此,當您呼叫 FeatureManager.IsEnabledAsync時,您必須直接傳遞它。 使用 ContextualTargetingFilter支援這種類型的環境定義。 需要將目標內容傳送至功能管理員的應用程式應該使用ContextualTargetingFilter而非TargetingFilter.

因為ContextualTargetingFilter實作了IContextualTargetingFilter<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"
        ]
    }
}

上述程式碼會為名為 JeffAlicia的使用者啟用功能。 此功能也會針對名為 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; }
}

擷取變體

針對每個功能,您可以使用 IVariantFeatureManager 介面的 GetVariantAsync 方法來擷取變體。

…
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 屬性。 另一個選項是使用 .NET 組態繫結模式,將組態繫結至物件。

IConfigurationSection variantConfiguration = variant.Configuration;

MyFeatureSettings settings = new MyFeatureSettings();

variantConfiguration.Bind(settings);

傳回的變體依據正在被評估的使用者而定。 您可以從 的 TargetingContext實例取得使用者的相關資訊。 當您呼叫 GetVariantAsync 時,您可以在此內容中傳遞。 或者,如果已註冊,則可以從 ITargetingContextAccessor 的實作中自動擷取。

變體功能旗標宣告

與標準特徵旗標相比,變體特徵旗標有兩個額外的屬性: variantsallocation。 屬性 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"
                    } 
                ]
            }
        ]
    }
}

定義變體

每個變體都有兩個屬性:名稱和組態。 此名稱是用來參考特定變體,而組態是該變體的值。 您可以使用屬性 configuration_value 來指定組態。 此 configuration_value 屬性是內嵌組態,可以是字串、數字、布林值或組態物件。 如果您未設定屬性 configuration_value ,則傳回的變體屬性 Configurationnull

若要指定特徵的所有可能變體,請在屬性下 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 變體和群組清單。 如果目前使用者至少在其中一個群組中,則會指派變體。
percentile 變體和使用者計算百分比必須符合才能指派該變體的百分比範圍。
seed 百分比計算 percentile 所依據的值。 如果使用相同的 seed 值,則特定使用者的百分比計算在所有功能中都是相同的。 如果未指定值 seed ,則會根據特徵名稱建立預設種子。

如果未啟用功能,功能管理員會將指定的 default_when_disabled 變體指派給目前使用者。 在上述範例中,該功能稱為 Small

如果啟用此功能,功能管理員將依該順序檢查 usergrouppercentile 配置,以指派變體。 在上述範例中,在下列情況下,會將指定的變體 Big指派給使用者:

  • 正在評估的使用者名為 Marsha
  • 使用者在 Ring1 群組中。
  • 使用者恰好介於第0個和第10個百分位數之間。

如果這些分配都不相符, default_when_enabled 則會將變體指派給使用者。 在此範例中,該變體是 Small

配置邏輯類似於您用於 Microsoft.Targeting 功能篩選的邏輯。 但是,定位中存在的一些參數不在分配中,反之亦然。 目標的結果與配置無關。

附註

若要配置功能變體,您需要透過呼叫WithTargeting<T>方法來註冊ITargetingContextAccessor

使用變體覆寫已啟用狀態

您可以使用變體來覆寫功能旗標的已啟用狀態。 當您利用此功能時,您可以擴充功能旗標的評估。 在具有變體的旗標上呼叫 IsEnabledAsync 時,功能管理員會檢查指派至目前使用者的變體是否已設定為覆寫結果。

您可以使用選用的變體屬性 status_override來實作覆寫。 此屬性可以具有下列值:

  • None:變體不會影響旗標是否被視為已啟用或已停用。 None 為預設值。
  • Enabled:選擇變體時,功能旗標會評估為已啟用。
  • Disabled:選擇變體時,功能旗標會評估為已停用。

您無法覆寫 enabled 狀態為 false 的功能。

如果您將功能旗標與二進位變體搭配使用,則屬性 status_override 可能會很有幫助。 您可以繼續在應用程式中使用 API ( IsEnabledAsync 例如 和 FeatureGateAttribute )。 但您也可以從變體附帶的功能中受益,例如百分位數分配和使用種子值進行百分比計算。

{
    "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");

您必須透過像 services.AddSingleton<IAlgorithm, SomeImplementation>() 這樣的新增方法,分別新增每個 IAlgorithm 的實作。 IVariantServiceProvider 所使用的 IAlgorithm 實作取決於 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。 遙測狀態由將 enabled 設定為 truetelemetry 物件指出。 enabled 屬性的值必須是 true 才能發佈旗標的遙測。

功能旗標的 telemetry 區段具有下列屬性:

屬性 描述
enabled 布林值,指定是否應該發佈功能旗標的遙測。
metadata 模型化為字典的索引鍵/值組集合,可用來將功能旗標的相關自訂中繼資料附加至評估事件。

自訂遙測發佈

功能管理員有自己的 ActivitySource 例項,名為 Microsoft.FeatureManagement。 如果功能旗標已啟用遙測:

  • 當功能旗標評估啟動時,功能管理員會啟動實例 Activity
  • 當功能旗標評估完成時,功能管理員會將名為ActivityEvent的實例新增至目前的FeatureFlag活動。

事件 FeatureFlag 具有包含功能旗標評估相關資訊的標籤。 標籤會使用 FeatureEvaluationEvent 結構描述中定義的欄位。

附註

功能旗標屬性中 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(應用洞察)遙測

Microsoft.FeatureManagement.Telemetry.ApplicationInsights 套件提供內建的遙測發行者,可將功能旗標評估資料傳送至 Application InsightsMicrosoft.FeatureManagement.Telemetry.ApplicationInsights 套件也會提供遙測初始設定式,自動以 TargetingId 標記所有事件,讓事件可以連結至旗標評估。 若要利用這項功能,請新增套件的參考,並註冊 Application Insights 遙測。 下列程式碼提供一個範例:

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

附註

若要協助確保 Application Insights 遙測如預期般運作,您應該使用類別 TargetingHttpContextMiddleware

若要在目前活動中啟用目標內容的持續性,您可以使用類別 TargetingHttpContextMiddleware

app.UseMiddleware<TargetingHttpContextMiddleware>();

如需其使用方式的範例,請參閱 VariantAndTelemetryDemo 範例。

必要條件

Microsoft.FeatureManagement.Telemetry.ApplicationInsights 套件提供的遙測發行者需要設定 Application Insights 並註冊為應用程式服務。 如需範例程式碼,請參閱 VariantAndTelemetryDemo 範例應用程式。

Caching

功能狀態是由 IConfiguration 系統提供。 設定提供者應負責處理任何快取和動態更新。 功能管理員 IConfiguration 會在評估功能是否已啟用時,要求提供功能狀態的最新值。

快照式

某些案例需要功能的狀態在要求的存留期內保持一致。 如果在要求期間,標準實作中提取的來源被更新,則從該標準實作傳回的值可能會變更。

您可以使用IVariantFeatureManagerSnapshot防止此行為。 您可以以與 IVariantFeatureManagerSnapshot相同的方式擷取IVariantFeatureManagerIVariantFeatureManagerSnapshot 實作 IVariantFeatureManager 介面,但 IVariantFeatureManagerSnapshot 在請求期間對特性的首次評估狀態進行快取。 它會在功能的存留期內傳回該狀態。

自訂功能提供者

當您實作自訂功能提供者時,您可以從資料庫或功能管理服務等來源提取功能旗標。 預設功能提供者會從 .NET Core 組態系統提取功能旗標。 此系統支援在 appsettings.json 檔案或 Azure 應用程式設定等組態提供者中定義功能。 您可以自訂此行為,以控制從何處讀取特徵定義。

若要自訂功能定義的載入,您必須實作 IFeatureDefinitionProvider 介面。

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

    IAsyncEnumerable<FeatureDefinition> GetAllFeatureDefinitionsAsync();
}

若要使用IFeatureDefinitionProvider的實作,您必須先將它新增至服務集合中,才能新增功能管理。 下列範例會新增名為 InMemoryFeatureDefinitionProviderIFeatureDefinitionProvider 實作。

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

後續步驟

若要瞭解如何在應用程式中使用功能旗標,請參閱下列快速入門:

若要瞭解如何使用功能篩選器,請參閱下列教學課程: