首页 > 解决方案 > .net Core 中的自定义属性设置

问题描述

我正在编写一个非常简单的自定义属性,以便与我的 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填充它才能工作,但我不想每次使用它时都将它传递给构造函数。配置它的最佳方法是什么?我正在考虑在属性中设置一个静态属性,但认为这有点蹩脚的方法,必须有更好的方法。提前致谢!

标签: c#.net.net-corecustom-attributes

解决方案


或者,您可以将 的创建提取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


推荐阅读