.net Core中的自定义属性设置

时间:2019-07-02 08:57:17

标签: c# .net .net-core custom-attributes

我正在编写一个非常简单的自定义属性,以与我的ASP.net Core方法一起使用。该属性用于处理特征标记,这些特征标记指示端点方法已“打开或关闭”,如下所示:

1)如果功能打开,则允许代码传递给方法并按常规执行。 2)如果该功能已关闭,则只需从属性中返回并不要执行其中的方法

我在想一些类似的事情:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class FeatureFlagAttribute : ActionFilterAttribute
{
    private Dictionary<string, bool> myFeaturesList;
    private readonly string selectedFeature;

    public FeatureFlagAttribute(string featureName)
    {
        selectedFeature = featureName;
    }

    public override void OnActionExecuting(ActionExecutingContext context)
    {
        var found = myFeaturesList.TryGetValue(selectedFeature, out var result);

        if (!found || !result)
        {
            // dont continue
            context.HttpContext.Response.StatusCode = 403;
        }
    }
}

我需要填充myFeaturesList才能起作用,但是我不想每次使用它时都将其传递给构造函数。什么是配置此的最佳方法?我当时在考虑在属性中设置一个静态属性,但是认为这有点a脚,必须有更好的方法。预先感谢!

2 个答案:

答案 0 :(得分:1)

一种不同的方法,但是也许将其移出属性,也许使用静态事件作为API挂钩?那么您可以将字典放到想要的地方

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class FeatureFlagAttribute : ActionFilterAttribute
{
    public FeatureFlagAttribute(string featureName)
    {
        selectedFeature = featureName;
    }

    public override void OnActionExecuting(ActionExecutingContext context)
    {
        if (IsActive?.Invoke(selectedFeature) == false)
        {
            // dont continue
            context.HttpContext.Response.StatusCode = 403;
        }
    }
    public static event Func<string, bool> IsActive;
}

(请注意,静态事件要小心,以免引起内存泄漏)


或者,保留您所拥有的内容,但是将字典设为静态(并且受线程保护等);然后添加某种API,例如:

public static void SetFeatureEnabled(string featureName, bool enabled);

调整静态字典。

答案 1 :(得分:1)

或者,您可以将featureNames的创建提取到可注入服务(注册到DI)中,并将属性用作类型过滤器或与IFilterFactory一起使用。

使用类型过滤器,您可以将属性创建为:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class FeatureFlagAttribute : ActionFilterAttribute
{
    private readonly string _featureName;
    private readonly IFeatureService _featureService;

    public FeatureFlagAttribute(string featureName, IFeatureService featureService)
    {
        _featureName = featureName;
        _featureService = featureService;
    }

    public override void OnActionExecuting(ActionExecutingContext context)
    {
        var features = _featureService.GetMyFeatures();
        var found = features.TryGetValue(_featureName, out var result);

        if (!found || !result)
        {
            // don't continue
            context.HttpContext.Response.StatusCode = 403;
        }
    }
}

在构造函数参数中,featureName保持不变,需要将其定义为属性,而featureService将通过DI进行解析,因此您需要为此注册实现。创业公司的ConfigureServices()

属性用法随类型过滤器的变化而有所变化,例如:

[TypeFilter(typeof(FeatureFlagAttribute), Arguments = new object[] { "feature-A" })]
public IActionResult Index()
{
    return View();
}

您可以在文档中阅读更多将依赖项注入过滤器的选项: https://docs.microsoft.com/en-us/aspnet/core/mvc/controllers/filters?view=aspnetcore-2.2#dependency-injection