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
Il nuovo controllo Range di Blazor 9
Creare una libreria CSS universale: Clip-path
Path addizionali per gli asset in ASP.NET Core MVC
Configurare e gestire sidecar container in Azure App Service
Conoscere il rendering Server o WebAssembly a runtime in Blazor
Generare una User Delegation SAS in .NET per Azure Blob Storage
Managed deployment strategy in Azure DevOps
Collegare applicazioni server e client con .NET Aspire
Usare i settings di serializzazione/deserializzazione di System.Text.Json di ASP.NET all'interno di un'applicazione non web
Eseguire query per recuperare il padre di un record che sfrutta il tipo HierarchyID in Entity Framework
Eseguire i worklow di GitHub su runner potenziati
Popolare una classe a partire dal testo, con Semantic Kernel e ASP.NET Core Web API
I più letti di oggi
- .NET Conference Italia 2024 - Milano
- Develop and distribute Azure Functions using K8s and CI/CD
- Disponibile la versione finale di Hyper-V: la virtualizzazione per Windows Server 2008
- Speciale Mastering Entity Framework
- Velocity arriva alla CTP3
- Silverlight Summer: un'estate speciale piena di Style per i controlli Silverlight!
- Disponibile la versione beta di Silverlight 4.0
- Mono 0.13: ora anche web services
- .NET Alerts Software Development Kit