Данное руководство устарело. Актуальное руководство: Руководство по ASP.NET Core 7
Фильтры могут принимать некоторые значения из вне. Для их приема мы можем определить в классе фильтра конструктор с соответствующими параметрами. Например:
public class SimpleResourceFilter : Attribute, IResourceFilter { int _id; string _token; public SimpleResourceFilter(int id, string token) { _id = id; _token = token; } public void OnResourceExecuted(ResourceExecutedContext context) { } public void OnResourceExecuting(ResourceExecutingContext context) { context.HttpContext.Response.Headers.Add("Id", _id.ToString()); context.HttpContext.Response.Headers.Add("Token", _token); } }
Здесь конструктор фильтра принимает два параметра. При применении фильтра мы можем передать значения для этих параметров:
public class HomeController : Controller { [SimpleResourceFilter(30, "8h6ell3o5wor5ld8")] public IActionResult Index() { return View(); } }
Если фильтр устанавливается глобально, то также при его установке необходимо передать ему нужные значения:
public void ConfigureServices(IServiceCollection services) { services.AddControllersWithViews() .AddMvcOptions(options=> options.Filters.Add(new SimpleResourceFilter(22, "jkrgbjkjgjghddw"))); }
Как и любые классы в ASP.NET Core, фильтры также могут принимать зависимости, устанавливаемые при старте приложения. Однако, если фильтр применяется непосредственно к контроллеру или его методу, то установка зависимостей через встроенный механизм Dependency Injection не будет работать. Все потому, что при применении атрибутов все значения должны быть переданы напрямую в их конструктор. Чтобы обойти это ограничение, надо использовать один из классов ServiceFilterAttribute или TypeFilterAttribute.
Например, пусть класс фильтра получает зависимость ILoggerFactory, которая позволяет создать объект логгера для логгирования событий приложения:
using Microsoft.AspNetCore.Mvc.Filters; using Microsoft.Extensions.Logging; using System; public class SimpleResourceFilter : Attribute, IResourceFilter { ILogger _logger; public SimpleResourceFilter(ILoggerFactory loggerFactory) { _logger = loggerFactory.CreateLogger("SimpleResourceFilter"); } public void OnResourceExecuted(ResourceExecutedContext context) { _logger.LogInformation($"OnResourceExecuted - {DateTime.Now}"); } public void OnResourceExecuting(ResourceExecutingContext context) { _logger.LogInformation($"OnResourceExecuting - {DateTime.Now}"); } }
Класс ServiceFilterAttribute извлекает экземпляр фильтра напрямую из DI. Для этого при применении ему передается тип фильтра:
[ServiceFilter(typeof(SimpleResourceFilter))] public class HomeController : Controller { public IActionResult Index() { return View(); } }
Но чтобы данный фильтр стал доступен, его еще надо зарегистрировать в методе ConfigureServices()
класса Startup:
public void ConfigureServices(IServiceCollection services) { services.AddControllersWithViews(); services.AddScoped<SimpleResourceFilter>(); }
Класс TypeFilterAttribute создает объект фильтра с помощью фабрики
Microsoft.Extensions.DependencyInjection.ObjectFactory
, а с помощью механизма DI устанавливает все зависимости для создаваемого фильтра.
В этом случае класс фильтра больше не надо регистрировать в ConfigureServices().
Применение TypeFilterAttribute аналогично ServiceFilterAttribute:
[TypeFilter(typeof(SimpleResourceFilter))] public class HomeController : Controller { public IActionResult Index() { return View(); } }