实现一个基于 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 效果就是可以正常访问:

feature enable

禁用的效果,默认是返回一个 404,如果需要也可以自定义,只需要实现一个接口,注入进去即可

feature disable

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 写一个 GetAppSetting 扩展方法

以上是关于实现一个基于 IConfiguration 的低配版 FeatureFlag的主要内容,如果未能解决你的问题,请参考以下文章

基于matlab的低秩结构重构算法仿真实现,对比ALM,IT,APG,ADMM

基于FPGA的低通滤波器,通过verilog实现并提供testbench测试文件

基于并行搜索的低信噪比环境下GPS信号检测算法FPGA实现

用Java仿一个低配版的Everything软件

Java利用Java的注解和反射实现一个"低配版"的依赖注入

Node/JavaScript论一个低配版Web实时通信库是如何实现的1( WebSocket篇)