实现一个基于 IConfiguration 的低配版 FeatureFlag
實現一個基于 IConfiguration 的低配版 FeatureFlag
Intro
在我們的應用中,可能有一些配置開關的需求,某些功能是否啟用使用一個配置開關,用的時候就打開,不用的時候就關掉,于是基于 .NET Core 的里配置體系寫了一個簡單的 FeatureFlag,類似于之前的 AppSetting 的擴展?給 IConfiguration 寫一個 GetAppSetting 擴展方法
Sample
首先來看一個實現效果:
[HttpGet("[action]")] [FeatureFlagFilter("Flag1",?DefaultValue?=?true)] public?IActionResult?FeatureEnableTest() {return?Ok(new{Time?=?DateTime.UtcNow}); }[HttpGet("[action]")] [FeatureFlagFilter("Flag2",?DefaultValue?=?false)] public?IActionResult?FeatureDisableTest() {return?Ok(new{Time?=?DateTime.UtcNow}); }這是兩個完全一樣的 API,為了測試 featureFilter 的功能
啟用的 API 效果就是可以正常訪問:
feature enable禁用的效果,默認是返回一個 404,如果需要也可以自定義,只需要實現一個接口,注入進去即可
feature disableImplement
實現代碼其實也比較簡單,分為兩部分,一部分是 IConfiguration 的擴展,從配置中獲取某個配置開關的值,另外一部分則是 ASP.NET Core 相關的擴展,上面的示例是一個 MVC Filter 的一個示例,比較簡單所以我們就直接看代碼
IConfiguration 擴展實現代碼如下:
public?static?string?FeatureFlagsSectionName?=?"FeatureFlags";public?static?bool?TryGetFeatureFlagValue(this?IConfiguration?configuration,?string?featureFlagName,?out?bool?featureFlagValue) {featureFlagValue?=?false;var?section?=?configuration.GetSection(FeatureFlagsSectionName);if?(section.Exists()){return?bool.TryParse(section[featureFlagName],?out?featureFlagValue);}return?false; }public?static?bool?IsFeatureEnabled(this?IConfiguration?configuration,?string?featureFlagName,?bool?defaultValue?=?false) {if?(TryGetFeatureFlagValue(configuration,?featureFlagName,?out?var?value)){return?value;}return?defaultValue; }上面示例中的 FeatureFlagFilter 是一個 MVC 的 ResourceFilter,實現代碼如下:
public?interface?IFeatureFlagFilterResponseFactory {public?Task<IActionResult>?GetResponse(ResourceExecutingContext?resourceExecutingContext); }[AttributeUsage(AttributeTargets.Class?|?AttributeTargets.Method,?AllowMultiple?=?false,?Inherited?=?true)] public?sealed?class?FeatureFlagFilterAttribute?:?Attribute,?IAsyncResourceFilter {public?bool?DefaultValue?{?get;?set;?}public?string?FeatureFlagName?{?get;?}public?FeatureFlagFilterAttribute(string?featureFlagName){FeatureFlagName?=?featureFlagName????throw?new?ArgumentNullException(nameof(featureFlagName));}public?async?Task?OnResourceExecutionAsync(ResourceExecutingContext?context,?ResourceExecutionDelegate?next){var?configuration?=?context.HttpContext.RequestServices.GetRequiredService<IConfiguration>();if?(configuration.IsFeatureEnabled(FeatureFlagName,?DefaultValue)){await?next();}else{var?responseFactory?=?context.HttpContext.RequestServices.GetService<IFeatureFlagFilterResponseFactory>();if?(responseFactory?!=?null){context.Result?=?await?responseFactory.GetResponse(context);}else{context.Result?=?new?NotFoundResult();}}} }More
關于 FeatherFlag,上面只是一個簡單的封裝,微軟有一個功能更為豐富的庫來支持 Microsoft.FeatureManagement.AspNetCore,? 源代碼在 Github 上有需要的可以參考?https://github.com/microsoft/FeatureManagement-Dotnet
以上示例代碼可以從 Github 獲取:https://github.com/WeihanLi/WeihanLi.Web.Extensions/blob/dev/samples/WeihanLi.Web.Extensions.Samples/ValuesController.cs
References
https://github.com/WeihanLi/WeihanLi.Web.Extensions/blob/dev/samples/WeihanLi.Web.Extensions.Samples/ValuesController.cs
https://github.com/WeihanLi/WeihanLi.Web.Extensions/blob/dev/src/WeihanLi.Web.Extensions/Middleware/FeaturedMiddleware.cs
https://github.com/WeihanLi/WeihanLi.Common/blob/dev/src/WeihanLi.Common/Extensions/ConfigurationExtension.cs#L131
https://github.com/microsoft/FeatureManagement-Dotnet
https://www.nuget.org/packages/Microsoft.FeatureManagement.AspNetCore/
給 IConfiguration 寫一個 GetAppSetting 擴展方法
總結
以上是生活随笔為你收集整理的实现一个基于 IConfiguration 的低配版 FeatureFlag的全部內容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: 官宣,11月8号,.NET6+64位VS
 - 下一篇: 如何分析 StackOverflow 异