news 2026/5/3 21:35:29

.NET 应用如何优雅的做功能开关(Feature Flag)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
.NET 应用如何优雅的做功能开关(Feature Flag)

目录

.NET 功能管理库

安装功能管理库

添加功能开关配置项

使用功能开关

在 Controller 级别添加功能开关

在 Action 级别添加功能开关

在 View 上添加功能开关

根据功能开关添加 Filter

根据功能开关添加 Middleware

小提示


导语

曾经,我们要在应用程序里做功能开关,就避免不了在配置文件里加上一堆 bool 类型的配置项,然后在代码里用 if else 去判断。尽管这种做法是可行的,但我们现在有办法让代码更加整洁,避免成堆的 if else 出现。

.NET 功能管理库

微软为了解决常见的功能开关问题场景,推出了 .NET Core Feature Management 库。它由 Azure 团队发布,并属于 Azure 文档的一部分,但我发现就算在没有 Azure 环境的情况下,它依然可以正常全功能运行

Azure 在此的作用仅仅是用 Azure App Configuration 作为功能开关的数据源,而我们完全可以用本地的 appsettings.json 来替代,避免了购买 Azure 从而落魄街头的风险

安装功能管理库

以我的博客系统为例,我的应用是 ASP.NET MVC / Web API类型的,我需要添加的包为Microsoft.FeatureManagement.AspNetCore。如果你的应用并非ASP.NET,可以只添加Microsoft.FeatureManagement

<PackageReference Include="Microsoft.FeatureManagement" Version="2.2.0" />

然后注册到 DI 里去

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

添加功能开关配置项

以我的博客系统为例,原先我在 AppSettings section 中有两个bool类型的配置项,现在就可以迁移到名为FeatureManagement的新 section 里。

相对应的,在 C# 代码里,去掉原来的项,添加一个新的枚举类型,值的名称对应配置项的名称。

这个枚举类型不是必须的,但非常建议创建枚举,这是为了保证在使用功能开关的时候有强类型支持,避免用string导致哪里名字没改对造成996。

使用功能开关

我们只需从DI里拿到 IFeatureManager 的实例,即可判断功能开关是否打开。例如:

IFeatureManager featureManager; ... if (await featureManager.IsEnabledAsync(nameof(MyFeatureFlags.FeatureA))) { // 执行代码 }

在 ASP.NET 项目里,最方便的就是通过构造函数获取 IFeatureManager 的实例

public class HomeController : Controller { private readonly IFeatureManager _featureManager; public HomeController(IFeatureManager featureManager) { _featureManager = featureManager; } }

那么问题来了,说好的少写 if else 呢?这个 IsEnabledAsync 不还是得写 if?

其实 Microsoft.FeatureManagement.AspNetCore 这个包包括了 MVC / Web API 项目所需要用到的许多助手功能。可以让我们避免大量的 if else。

在 Controller 级别添加功能开关

还是以我博客系统为例,我的 GraphController 只有在 EnableWebApi 开关打开的时候才响应用户请求,那么本来的 if else 判断现在就可以:

[FeatureGate(FeatureFlags.EnableWebApi)] // ... public class GraphController : ControllerBase { // ... }

是不是很爽?

在 Action 级别添加功能开关

[FeatureGate(FeatureFlags.EnableAudit)] public async Task<IActionResult> ClearAuditLogs() { // ... }

在 View 上添加功能开关

先在 _ViewImports.cshtml 中添加 taghelper 声明。

@addTagHelper *, Microsoft.FeatureManagement.AspNetCore

然后就可以用 <feature> 标签选择性的渲染 HTML 内容了!

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

对于feature关闭才显示的内容,加个 negate 就好了

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

还可用 All, Any 属性控制多个功能开关的显示处理。All 表示列出的功能得全启用才执行,Any 表示列出的功能里任意一个为 true 就可以执行。

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

根据功能开关添加 Filter

使用 AddForFeature() 拓展方法

using Microsoft.FeatureManagement.FeatureFilters; IConfiguration Configuration { get; set;} public void ConfigureServices(IServiceCollection services) { services.AddMvc(options => { options.Filters.AddForFeature<SomeMvcFilter>(nameof(MyFeatureFlags.FeatureA)); }); }

根据功能开关添加 Middleware

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

或者

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

小提示

功能开关的配置值更改,无需重启应用程序,修改配置文件后可以热更新,立即生效!

另外,如果你足够有钱,也推荐试试 Azure App Configuration,将你的应用功能开关放在云端统一管理,可以非常方便的针对用户群体配置 A/B,蓝绿测试哦!

参考文档:https://docs.microsoft.com/en-us/azure/azure-app-configuration/use-feature-flags-dotnet-core?WT.mc_id=AZ-MVP-5002809

引入地址

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/3 16:32:56

Unsloth快速入门指南:5步完成LLM微调任务

Unsloth快速入门指南&#xff1a;5步完成LLM微调任务 1. 学习目标与环境准备 本文将带你使用 Unsloth 框架&#xff0c;通过 5个清晰步骤 完成大语言模型&#xff08;LLM&#xff09;的高效微调。你将学会如何在有限显存条件下&#xff0c;快速加载并微调如 Qwen、Llama 等主…

作者头像 李华
网站建设 2026/4/27 1:07:26

无需专业设备:用云端GPU实现高效图片旋转判断

无需专业设备&#xff1a;用云端GPU实现高效图片旋转判断 你是不是也遇到过这样的烦恼&#xff1f;客户发来几百张照片&#xff0c;每张方向都不一样——有的横着、有的竖着、甚至还有倒着的。作为摄影工作室老板&#xff0c;手动一张张调整不仅费时费力&#xff0c;还容易出错…

作者头像 李华
网站建设 2026/4/23 13:00:42

bert-base-chinese命名实体识别实战:免配置10分钟上手

bert-base-chinese命名实体识别实战&#xff1a;免配置10分钟上手 你是不是也遇到过这种情况&#xff1a;手头有个紧急的医学信息提取任务&#xff0c;比如要从一堆电子病历里快速找出患者的疾病名称、用药记录、手术史这些关键信息&#xff0c;但实验室电脑老旧&#xff0c;连…

作者头像 李华
网站建设 2026/4/23 9:58:36

小白必看!Qwen3-VL多模态AI保姆级教程:从图片上传到智能问答

小白必看&#xff01;Qwen3-VL多模态AI保姆级教程&#xff1a;从图片上传到智能问答 1. 引言&#xff1a;为什么你需要了解 Qwen3-VL&#xff1f; 在人工智能飞速发展的今天&#xff0c;多模态大模型正逐渐成为连接人类与机器认知的桥梁。传统的语言模型只能“听懂”文字&…

作者头像 李华
网站建设 2026/5/2 7:34:19

Z-Image-Turbo为何报错CUDA?GPU驱动兼容性解决步骤

Z-Image-Turbo为何报错CUDA&#xff1f;GPU驱动兼容性解决步骤 1. 问题背景与技术定位 在部署阿里通义Z-Image-Turbo WebUI图像生成模型时&#xff0c;许多用户反馈启动过程中出现 CUDA相关错误&#xff0c;典型表现为&#xff1a; RuntimeError: CUDA error: no kernel ima…

作者头像 李华
网站建设 2026/5/2 1:39:06

Qwen3-VL-8B影视分镜分析:导演助手,10倍速读剧本

Qwen3-VL-8B影视分镜分析&#xff1a;导演助手&#xff0c;10倍速读剧本 你是不是也遇到过这样的情况&#xff1f;作为独立电影人&#xff0c;想深入研究《肖申克的救赎》或《寄生虫》这类经典影片的镜头语言&#xff0c;却只能一遍遍手动暂停、截图、标注。不仅耗时耗力&…

作者头像 李华