Типичный шаблон, который я видел для реализации пользовательского фильтра, является производным от, например, ActionFilterAttribute
и переопределить метод OnActionExecutingAsync()
:
public class CustomActionFilter : ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext actionContext)
{
// Custom code here...
}
}
Документация для веб-API 2 (я знаю, ядро существует, но я еще не перешел) рекомендует реализовать его следующим образом:
В Web API фильтры аутентификации реализуют интерфейс System.Web.Http.Filters.IAuthenticationFilter. Они также должны наследоваться от System.Attribute для применения в качестве атрибутов.
Однако, наследуя от атрибута, вы теряете возможность выполнять внедрение зависимостей . Также просто неправильно вводить логику в атрибут - имя 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 выбрала первый способ реализации. Каковы недостатки сохранения атрибута и реализации отдельно?