c# 中应使用 microsoft.featuremanagement 库替代手写 bool 开关,它支持配置化、灰度、热更新;注册时须调用 addfeaturemanagement()、配置含 "featuremanagement" 节点(或指定自定义节)、web 场景必用 isenabledasync;开关名区分大小写,未定义默认 false;灰度需用 enabledfor 对象语法;默认 30 秒缓存,调试时可用 ifeaturemanagersnapshot 绕过。

直接上结论:C# 中不该手写 bool featureFlag = true 再套 if (featureFlag),而是用 Microsoft.FeatureManagement 库——它让开关可配置、可灰度、可热更新、不阻塞线程,且与 ASP.NET Core 生命周期天然对齐。
注册服务时最容易漏的三件事
没调 AddFeatureManagement(),DI 容器里压根没有 IFeatureManager;appsettings.json 里缺 "FeatureManagement" 节点;用了自定义节名(比如 "MyFlags")但没传参指定。
- 必须在
Program.cs(.NET 6+)里显式注册:builder.Services.AddFeatureManagement(); - 对应配置节必须存在,哪怕只开一个开关:
"FeatureManagement": { "NewCheckout": true, "BetaDashboard": false } - 如果开关放在
"MyFlags"下,得手动指定节:builder.Services.AddFeatureManagement(Configuration.GetSection("MyFlags"));
IsEnabledAsync 和 IsEnabled 到底该用哪个
99% 的 Web 场景必须用 IsEnabledAsync。同步版 IsEnabled 不走异步管道,会阻塞请求线程,且不兼容任何基于用户、时间、百分比的动态筛选器。
-
IsEnabledAsync("NewCheckout")返回Task<bool></bool>,需await,支持所有评估器 -
featureName区分大小写:"newcheckout"≠"NewCheckout" - 配置里没定义该 flag?默认返回
false,不会抛异常 - 默认启用 30 秒缓存——改了
appsettings.json不会立刻生效;要强制重查,换用IFeatureManagerSnapshot
配置文件里怎么写带条件的开关(比如只对 20% 用户开启)
纯布尔值只能全量开关。真要灰度,得用对象语法声明 EnabledFor 筛选器列表。每个筛选器按顺序执行,只要有一个返回 true,整个 flag 就算启用。
- 按百分比分流:
"FeatureC": { "EnabledFor": [{ "Name": "Percentage", "Parameters": { "Value": 20 } }] } - 按用户角色:
"Name": "Role", "Parameters": { "AllowedRoles": ["Admin", "BetaTester"] } - 多个筛选器短路执行——例如先查角色,再查时间窗,只要角色匹配就跳过后续
最常被忽略的是缓存行为:默认 30 秒缓存不是“可选优化”,而是硬编码策略。如果你在本地调试时改了配置却没生效,大概率不是代码问题,而是卡在缓存里——这时候别 reload 项目,直接换 IFeatureManagerSnapshot 实例就行。










