点击上方蓝字关注“汪宇杰博客”

导语

曾经,我们要在应用程序里做功能开关,就避免不了在配置文件里加上一堆 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 p 中有两个bool类型的配置项,现在就可以迁移到名为 FeatureManagement 的新 p 里。

相对应的,在 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

汪宇杰博客

Azure | .NET | 微软 MVP

无广告,不卖课,做纯粹的技术公众号

喜欢本篇内容请点个在看

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

  1. .net core 不启用 https_.NET 应用如何优雅的做功能开关(Feature Flag)

    点击上方蓝字关注"汪宇杰博客" 导语 曾经,我们要在应用程序里做功能开关,就避免不了在配置文件里加上一堆 bool 类型的配置项,然后在代码里用 if else 去判断.尽管这种做 ...

  2. .NET应用如何优雅的实现功能定时开关

    点击上方蓝字关注"汪宇杰博客" 导语 我们在打工的时候,总能遇到一种类型的需求:"我想要这个活动广告在双11期间才显示","我想要这个API在20号以 ...

  3. 微服务配置组件变色龙Archaius

    介绍 如果我们要设计开发一套微服务基础架构,大家觉得哪个组件是最基础的?基于多年互联网分布式系统的实战经验,我的回答是配置中心以及配套的客户端.之前我在极客时间上的课程<微服务架构和实践160讲 ...

  4. 幽灵代码删库跑路引发的分支模式思考

    Photo @  Akshar Dave 文  |  故知 背景--讲个真实的"鬼"故事 菜鸟 CTO 线研发效能团队开发了一个大促协同平台,来提高大家在处理大促相关工作时的协同效 ...

  5. 万字长文 - 解读功能开关 | IDCF

    原文:https://martinfowler.com/articles/feature-toggles.html 作者:Pete Hodgson 译者:冬哥 功能开关Feature Toggle(通 ...

  6. ASP.NET Core使用功能开关控制路由访问

    前言 在前面的文章,我们介绍了使用Middleware有条件地允许访问路由(<ASP.NET Core使用Middleware有条件地允许访问路由>). 而对于一些试验性的功能,我们并不希 ...

  7. .Net Core功能开关实战

    为了快速发布开发完成的功能,企业通常会以比较快的迭代周期持续发布.但是由于某些 原因或场景,需要在发布的时候将某些功能隐藏起来或者小规模的开放(例如只有某些特定用户可以使用.或者特定日期开放),通过使 ...

  8. python flag 参数_flag_flagpython_js开关flag - 云+社区 - 腾讯云

    广告关闭 腾讯云11.11云上盛惠 ,精选热门产品助力上云,云服务器首年88元起,买的越多返的越多,最高返5000元! apple.stackexchange.comquestions336888wh ...

  9. Chromium命令行开关列表1

    Chromium命令行开关列表 Google Chrome浏览器可以使用很多命令行. 一些更改功能的行为,其他用于调试或试验. 该页面列出了可用的开关,包括其条件和说明. 上一次自动更新发生在2020 ...

最新文章

  1. 部署yum仓库与NFS服务
  2. 同程旅行王晓波:如何改变 Redis 用不好的误区
  3. pods报错修复方法
  4. 流式上传文件到服务器磁盘,在ASP.NET中流式传输大文件上传
  5. 合作博弈网页小游戏-Js源码
  6. distpicker初始化以及设定指定值
  7. VCSA5.5升级6.5u1提示VUM出错和证书错误的解决办法
  8. 高盛VR/AR报告完整解读版
  9. 用友系统中连接数据库服务器失败,用友u8服务器连接不到本地数据库
  10. B树,B+树,树,二叉树,满二叉树,完全二叉树,二叉搜索树,平衡二叉树,
  11. 五、入门python第五课
  12. solid works定义样条曲线
  13. 深度学习与人类语言处理学习笔记(二)—— 变声(理论篇)
  14. 代码实现微信8.0特效
  15. isbn书号查询php代码,php根据isbn书号查询amazon网站上的图书信息的示例_PHP教程
  16. android 不压缩保存图片格式,Android中图片的压缩方法
  17. 远程DNS缓存攻击__网络攻防实验三
  18. mysql源生的sql语句_Django执行源生mysql语句实现过程解析
  19. 莱布尼兹懂得超实数吗?
  20. CRS-4000启动crs报错问题处理

热门文章

  1. Python3——字典
  2. 如何让两个安装程序setup共享同一个component—— installing shared files(version:installshield develop8.0)...
  3. Eclipse设定文件的默认打开方式
  4. SQL 中的unicode字符
  5. InstallSield更新包快速入门文档----感谢原作者ㄣ齊¨彡仯乄的无私提供
  6. RFileWriteStream 写入汉字
  7. Teams Bot库的JSON
  8. 新垣结衣自拍照_如何阻止自拍照出现在iPhone的自拍照专辑中
  9. android 设备名称_如何更改您的Android TV的设备名称
  10. 使用lodash防抖_什么,lodash 的防抖失效了?