实现一个基于 IConfiguration 的低配版 FeatureFlag
Posted dotNET跨平台
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了实现一个基于 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 效果就是可以正常访问:
禁用的效果,默认是返回一个 404,如果需要也可以自定义,只需要实现一个接口,注入进去即可
Implement
实现代码其实也比较简单,分为两部分,一部分是 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 的低配版 FeatureFlag的主要内容,如果未能解决你的问题,请参考以下文章
基于matlab的低秩结构重构算法仿真实现,对比ALM,IT,APG,ADMM
基于FPGA的低通滤波器,通过verilog实现并提供testbench测试文件