最近開發流程從 Gitflow 改為 Trunk-Based,讓每個 Feature 能很快速地回到主幹分支,但頻繁交付有時也不會想把新功能推出在使用者面前,所以這時候就能用 Feature Flag 來管理這些還沒有要發佈的功能,本篇文章記錄一下如何在 .NET Core 加入此功能,並講解一下目前實務上常規化的 Flag

  1. Nuget 安裝
dotnet add package Microsoft.FeatureManagement.AspNetCore
  1. 加入 Feature Toggle
public void ConfigureServices(IServiceCollection services)
{
	// feature toggle
	services.AddFeatureManagement();
	
	services.AddControllers();
	services.AddSwaggerGen(c =>
	{
		c.SwaggerDoc("v1", new OpenApiInfo {Title = "FeatureFlagPoc.API", Version = "v1"});
	});
}
  1. 要使用時直接注入
private readonly IFeatureManager _featureManager;

public WeatherForecastController(ILogger<WeatherForecastController> logger, IFeatureManager featureManager)
{
	_logger = logger;
	_featureManager = featureManager;
}
  1. 基本的 Feature Toggle 使用
var isFeatureAEnabled = await _featureManager.IsEnabledAsync("FeatureA");
if(isFeatureAEnabled) {
    // 有打開,走新邏輯
}
else {
    // 未打開,走舊邏輯
}
  1. appsettings.json
"FeatureManagement": {
	"FeatureA": true
}
  1. API Route 多個使用方式,驗證不過會回傳404
[FeatureGate("FeatureA")]
public async Task<ActionResult> Foo()
{
    return Ok(result); 
}
  1. 也可指定任一或多個 Feature 是否有打開
[FeatureGate(requirementType: RequirementType.Any, "FeatureA", "FeatureB")]
public async Task<ActionResult> Foo()
{
    return Ok(result); 
}
  1. 也可以用 Enum 避免弱型別的typo
[FeatureGate(MyFeatureFlags.FeatureA)]
public enum MyFeatureFlags
{
	FeatureA
}

Toggle 定義

此篇文章值得一看,裡面提到實務上可以定義四種 Toggle 來區別用途

  • Release Toggles: 還未完成之功能, 通常 Release toggles 的變動頻率應該要是相當小的, 等版本推出後功能穩定後就會被拿掉,避免造成未來維護的成本
  • Experiment Toggles: 用在做A/B Test實驗, 如我自己會用在 LineBot 做不同文案的轉化追蹤
  • Ops Toggles: 用在跟系統運維相關, 可能需要臨時上維護公告,或者是臨時要開啟此程式片段的系統監控
  • Permission Toggles: 用在限定特定使用者可以使用, 針對有權限控制的功能做顯示/隱藏

Reference

https://github.com/microsoft/FeatureManagement-Dotnet