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
Generare HTML a runtime a partire da un componente Razor in ASP.NET Core
Utilizzare Copilot con Azure Cosmos DB
Generare una User Delegation SAS in .NET per Azure Blob Storage
Implementare l'infinite scroll con QuickGrid in Blazor Server
Fornire parametri ad un Web component HTML
Gestione degli eventi nei Web component HTML
Effettuare il refresh dei dati di una QuickGrid di Blazor
Sfruttare gli embedding e la ricerca vettoriale con Azure SQL Database
Garantire la provenienza e l'integrità degli artefatti prodotti su GitHub
Ottimizzare le performance delle collection con le classi FrozenSet e FrozenDictionary
Utilizzare DeepSeek R1 con Azure AI
Loggare le query più lente con Entity Framework
I più letti di oggi
- Disponibile l'Update 1 per Entity Framework 4.1
- Dal 29 febbraio arriva WinRTItalia.com: tutto sullo sviluppo per Windows 8 e Metro
- Annunciato Visual Studio 2013: la prima preview a fine mese a Build
- Anteprima del nuovo Web Matrix
- Le pubblicazioni riprenderanno il 12
- Microsoft Launch Tour 2006 a partire dal 7 marzo 2006