Come abbiamo più volte ribadito, la dependency injection è parte integrante del runtime di ASP.NET Core. Ovviamente il caso più tipico di utilizzo è costituito dai Controller, ai quali possiamo passare dipendenze semplicemente specificandole come parametri nel costruttore.
Una tecnica simile può essere utilizzata anche dagli ActionFilter. Immaginiamo per esempio di voler restituire tra gli header un'informazione di diagnostica circa il tempo di esecuzione della action. Per misurarlo potremmo creare un servizio come il seguente, che sfrutta la classe Stopwatch per la misurazione.
public class TimerService : ITimerService { private Stopwatch _start; public TimerService() { _start = Stopwatch.StartNew(); } public string GetElapsedTime() { var elapsed = _start.ElapsedMilliseconds; return $"{elapsed}ms"; } }
Affinché però tutto funzioni, è necessario che per ogni richiesta venga istanziato uno e un solo TimerService. Ecco perché, quindi, dobbiamo registrarlo come Scoped:
public void ConfigureServices(IServiceCollection services) { // ... services.AddScoped<ITimerService, TimerService>(); }
A questo punto possiamo finalmente costruire un ActionFilter per popolare l'Header in risposta:
public class TimerAttribute : ActionFilterAttribute { private ITimerService _service; public TimerAttribute(ITimerService service) { _service = service; } public override void OnActionExecuted(ActionExecutedContext context) { base.OnActionExecuted(context); context.HttpContext.Response.Headers .Add("ProcessingTime", _service.GetElapsedTime()); } }
Questo filtro accetta ITimerService nel costruttore e, al termine dell'esecuzione della action, aggiunge un Header alla risposta per indicare il tempo trascorso.
Ora abbiamo tutti gli ingredienti pronti e non dobbiamo far altro che sfruttare il nuovo fitro nella nostra action o in un controller. Purtroppo però, a causa del suo costruttore, questa classe non può essere direttamente utilizzata come attribute, ma è necessario referenziarla tramite l'attributo TypeFilter:
[TypeFilter(typeof(TimerAttribute))] public IActionResult Index() { Thread.Sleep(200); return View(); }
Se abbiamo svolto tutti i passaggi correttamente, vedremo una nuova header apparire nella risposta, come ci aspettiamo.
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
Approfondimenti
Utilizzare gRPC su App Service di Azure
Utilizzare la versione generica di EntityTypeConfiguration in Entity Framework Core
Aprire una finestra di dialogo per selezionare una directory in WPF e .NET 8
Sfruttare al massimo i topic space di Event Grid MQTT
Referenziare un @layer più alto in CSS
Generare la software bill of material (SBOM) in GitHub
Configurare il nome della run di un workflow di GitHub in base al contesto di esecuzione
Migliorare i tempi di risposta di GPT tramite lo streaming endpoint in ASP.NET Core
Code scanning e advanced security con Azure DevOps
Generare HTML a runtime a partire da un componente Razor in ASP.NET Core
Supportare lo HierarchyID di Sql Server in Entity Framework 8
Sostituire la GitHub Action di login su private registry
I più letti di oggi
- Effettuare il log delle chiamate a function di GPT in ASP.NET Web API
- ecco tutte le novità pubblicate sui nostri siti questa settimana: https://aspit.co/wkly buon week-end!
- Utilizzare il metodo CountBy di LINQ per semplificare raggruppamenti e i conteggi
- Creare una libreria CSS universale: Cards
- Eseguire script pre e post esecuzione di un workflow di GitHub