Middleware Pipeline

La pipeline AspNetCore è una dei concetti fulcro del sistema. Essa viene composta da una serie di classi chiamate Middleware che fungono da «step» da eseguire ad ogni richiesta. L’esecuzione avviene come segue

../_images/request-delegate-pipeline.png

La comodità e la praticità di questo sistema è data principalmente dalla semplicità della struttura unito al fatto che permette di interrompere il ciclo della richiesta senza dover ricorrere ad exception gestite alla base della pipeline che rendono il sistema imprevedibile se non utilizzate correttamente.

Grazie a questo sistema è possibile inserire e rimuovere logiche applicative prima o dopo logiche esistenti in quanto l’intera pipeline è sotto il controllo dell”utente

Per esempio, prendendo in considerazione alcune righe dal file Startup.cs dal progetto di default, possiamo notare come ci sia permesso disabilitare le funzionalità considerate come «integrate» e abilitarne di sostitutive/nuove

if (env.IsDevelopment()) {
    app.UseDeveloperExceptionPage();
} else {
    app.UseExceptionHandler("/Home/Error");
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();

app.UseMvc(routes => {
    routes.MapRoute(
        name: "default",
        template: "{controller=Home}/{action=Index}/{id?}");
});

Nota

Lo snippet qui inserito è stato preso dal metodo Configure un nuovo progetto AspNET Core MVC

L’aggiunta di un middleware personalizzato è molto semplice grazie ad un overload di Use che accetta una Func<HttpContext, Func<Task>, Task> mentre per interrompere la richiesta e servire un risultato in modo esplicito è resto disponibile anche il metodo Run, analogo a Use di qui sopra, al quale non viene passato la Func<Task> che rappresenta il middleware successivo (e la conseguente continuazione della pipeline)

app.Use(async (context, next) => {
    await context.Response.WriteAsync("Hello, World!");
});

L’implementazione di una classe Middleware AspNET Core isolata, invece, avviene come segue

public class RequestCultureMiddleware {
    private readonly RequestDelegate _next;

    public RequestCultureMiddleware(RequestDelegate next) {
        _next = next;
    }

    public async Task InvokeAsync(HttpContext context) {
        // Call the next delegate/middleware in the pipeline
        await _next(context);
    }
}

Nota

Tutti i middleware supportano il sistema di Service Injecting

Alternativamente è possibile implementare un metodo Invoke non asincrono