为什么ASP.NET筛选器属性中包含逻辑?

时间:2018-11-06 19:31:56

标签: c# asp.net asp.net-web-api

我看到的用于实现自定义过滤器的典型模式是从例如ActionFilterAttribute,并覆盖OnActionExecutingAsync()方法:

public class CustomActionFilter : ActionFilterAttribute
{
    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        // Custom code here...
    }
}

documentation for Web API 2(我知道,核心存在,但我还没有继续)建议您采用以下方式实现它:

  

在Web API中,身份验证筛选器实现System.Web.Http.Filters.IAuthenticationFilter接口。它们还应该继承自System.Attribute,以便用作属性。

但是,通过继承属性,您lose the ability to perform dependency injection。将逻辑放在属性中也感觉不对-名称Attribute暗示着这只是多余的信息。

可以将属性和过滤器逻辑保留为两个单独的类:

[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public class CustomActionAttribute : Attribute
{
}

public class CustomActionFilter : IActionFilter
{
    public bool AllowMultiple => false;
    public IDependency Dependency { get; }

    public CustomActionFilter(IDependency dependency)
    {
        Dependency = dependency;
    }

    public async Task<HttpResponseMessage> ExecuteActionFilterAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
    {
        if (!actionContext.ActionDescriptor.GetCustomAttributes<RequireClaimAttribute>(true).Any())
            return await continuation();

        // Custom code here
    }
}

我个人认为这是一种更清洁的解决方案,并且想知道为什么Microsoft选择了以前的实现方式。将属性和实现分开设置的不利之处是什么?

0 个答案:

没有答案