我正在编写一个非常简单的自定义属性,以与我的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脚,必须有更好的方法。预先感谢!
答案 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