.net Core 中的自定义属性设置
Custom Attribute settings in .net Core
我正在编写一个非常简单的自定义属性,用于 ASP.net Core 的方法。该属性用于处理指示端点方法为 "switched on or off" 的功能标志,如下所示:
1) 如果启用了某个功能,请允许代码通过该方法并正常执行它。
2) 如果该功能关闭,只需从属性 return 并且不执行
内的方法
我的思路是这样的:
[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
才能工作,但我不想每次使用它时都将它传递给构造函数。最好的配置方法是什么?我正在考虑在属性中设置一个 static 属性,但认为这是一个有点蹩脚的方法,必须有更好的方法。提前致谢!
一种不同的方法,但也许将其移出属性,或许使用静态事件作为 API 挂钩?然后你可以把你想要的字典 where-ever?
[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;
}
(注意静态事件需要注意不要造成内存泄露)
或者,保留现有的,但将字典设为静态(和 thread-protected,等等);然后添加某种 API,例如:
public static void SetFeatureEnabled(string featureName, bool enabled);
调整静态字典。
或者,您可以将 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
我正在编写一个非常简单的自定义属性,用于 ASP.net Core 的方法。该属性用于处理指示端点方法为 "switched on or off" 的功能标志,如下所示:
1) 如果启用了某个功能,请允许代码通过该方法并正常执行它。 2) 如果该功能关闭,只需从属性 return 并且不执行
内的方法我的思路是这样的:
[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
才能工作,但我不想每次使用它时都将它传递给构造函数。最好的配置方法是什么?我正在考虑在属性中设置一个 static 属性,但认为这是一个有点蹩脚的方法,必须有更好的方法。提前致谢!
一种不同的方法,但也许将其移出属性,或许使用静态事件作为 API 挂钩?然后你可以把你想要的字典 where-ever?
[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;
}
(注意静态事件需要注意不要造成内存泄露)
或者,保留现有的,但将字典设为静态(和 thread-protected,等等);然后添加某种 API,例如:
public static void SetFeatureEnabled(string featureName, bool enabled);
调整静态字典。
或者,您可以将 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