Il concetto di filter è presente in fin dalle prime versioni di ASP.NET MVC ed è stato pienamente ereditato anche in ASP.NET Core. Come probabilmente sappiamo, grazie ai filter è possibile aggiungere della logica a una specifica action, a un intero controller o anche a tutta l'applicazione.
Alle volte potremmo avere la necessità di iniettare dipendenze all'interno di un custom filter. Per esempio su un custom Authorize filter, vorremmo avere accesso al database degli utenti per leggere alcune informazioni sul profilo dell'utente stesso, o in un Resource filter vorremmo avere accesso alla cache per verificare se il dato richiesto è presente.
Immaginiamo ad esempio di aver realizzato un filtro simile al seguente, in cui segnaliamo nel log l'inizio e il completamento di una action:
public class LoggerFilter : IActionFilter { private ILogger<LoggerFilter> _logger; public LoggerFilter(ILogger<LoggerFilter> logger) { _logger = logger; } public void OnActionExecuted(ActionExecutedContext context) { _logger.LogDebug($"Action {context.ActionDescriptor.DisplayName} completed"); } public void OnActionExecuting(ActionExecutingContext context) { _logger.LogDebug($"Action {context.ActionDescriptor.DisplayName} starting"); } }
Questa classe necessita di un ILogger<T> come parametro di input. Ovviamente non possiamo definirla come Attribute perchè altrimenti non avremmo modo di fornire questo parametro nel costruttore.
L'alternatica allora è creare un secondo oggetto, che implementi IFilterFactory:
public class LoggerAttribute : Attribute, IFilterFactory { public bool IsReusable => true; public IFilterMetadata CreateInstance(IServiceProvider serviceProvider) { return serviceProvider.GetService<LoggerFilter>(); } }
Questa interfaccia espone un metodo CreateInstance in cui possiamo generare il filtro di cui effettivamente abbiamo bisogno, sfruttando il serviceProvider passato come parametro.
La nostra nuova classe LoggerAttribute eredita effettivamente da Attribute e può essere utilizzata direttamente sul controller o sulla action interessata.
[Route("api/[controller]")] [ApiController] [Logger] public class ValuesController : ControllerBase { ... }
Affinchè tutto funzioni, l'ultimo passaggio è registrare LoggerFilter nell'IoC container di ASP.NET Core all'interno della classe Startup:
public void ConfigureServices(IServiceCollection services) { // .. altro codice qui .. services.AddTransient<LoggerFilter>(); }
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
Approfondimenti
Installare le Web App site extension tramite una pipeline di Azure DevOps
Effettuare il binding di date in Blazor
gRPC con .NET
Utilizzare Tailwind CSS all'interno di React: installazione
Migliorare la sicurezza dei prompt con Azure AI Studio
Change tracking e composition in Entity Framework
Gestione dell'annidamento delle regole dei layer in CSS
Utilizzare un service principal per accedere a Azure Container Registry
Creazione di plugin per Tailwind CSS: espandere le funzionalità del framework dinamicamente
Visualizzare le change sul plan di Terraform tramite le GitHub Actions
Gestire i dati con Azure Cosmos DB Data Explorer
Filtrare i dati di una QuickGrid in Blazor con una drop down list