0Pricing
C# Academy · Lezione

Comportamenti della pipeline

Aggiunga logica trasversale con i behaviors.

Comportamenti della pipeline è una lezione C# Academy gratuita su CoddyKit. Questa è la lezione 3 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento C# Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso C# Academy include 4 lezioni in totale.

Funzionalità trasversali

Logging, convalida, misurazione dei tempi e transazioni si applicano a molti handler. Copiare questo codice in ogni handler è ripetitivo e soggetto a errori.

I comportamenti della pipeline di MediatR consentono di racchiudere ogni richiesta in una logica condivisa.

// One behavior runs around all handlers

IPipelineBehavior

Un comportamento implementa IPipelineBehavior<TRequest, TResponse>. Il suo metodo Handle riceve la richiesta e un delegato next che invoca il resto della pipeline.

public class LoggingBehavior<TRequest, TResponse>
    : IPipelineBehavior<TRequest, TResponse>
    where TRequest : notnull
{
    public async Task<TResponse> Handle(
        TRequest request,
        RequestHandlerDelegate<TResponse> next,
        CancellationToken ct)
    {
        // before
        var response = await next();
        // after
        return response;
    }
}

Il delegato next

next() chiama il comportamento successivo o l'handler effettivo se questo è l'ultimo. Il codice prima della chiamata viene eseguito durante l'ingresso; quello dopo viene eseguito durante l'uscita.

// [Behavior A in] -> [Behavior B in] -> [Handler]
//               <- [Behavior B out] <- [A out]

Un comportamento di logging

Un comportamento concreto di logging registra il nome della richiesta durante l'ingresso e il tempo trascorso durante l'uscita.

public async Task<TResponse> Handle(
    TRequest request,
    RequestHandlerDelegate<TResponse> next,
    CancellationToken ct)
{
    var name = typeof(TRequest).Name;
    _logger.LogInformation("Handling {Name}", name);
    var sw = Stopwatch.StartNew();
    var response = await next();
    _logger.LogInformation("{Name} took {Ms}ms", name, sw.ElapsedMilliseconds);
    return response;
}

Registrazione di un comportamento

Registri il comportamento generico aperto in DI. MediatR lo applicherà a ogni richiesta.

builder.Services.AddTransient(
    typeof(IPipelineBehavior<,>),
    typeof(LoggingBehavior<,>));

Un comportamento di convalida

Un uso comune è la convalida delle richieste con FluentValidation. Il comportamento esegue tutti i validatori prima dell'handler e genera un'eccezione se uno di essi fallisce.

public async Task<TResponse> Handle(
    TRequest request,
    RequestHandlerDelegate<TResponse> next,
    CancellationToken ct)
{
    var context = new ValidationContext<TRequest>(request);
    var failures = _validators
        .Select(v => v.Validate(context))
        .SelectMany(r => r.Errors)
        .Where(f => f is not null)
        .ToList();
    if (failures.Count != 0)
        throw new ValidationException(failures);
    return await next();
}

Interruzione anticipata

Un comportamento può saltare completamente l'handler restituendo il controllo senza chiamare next(): è utile per memorizzare nella cache i risultati delle query o rifiutare richieste non valide.

if (_cache.TryGet(key, out TResponse cached))
    return cached;          // handler never runs
var response = await next();
_cache.Set(key, response);
return response;

Ordinamento dei comportamenti

I comportamenti vengono eseguiti nell'ordine in cui sono registrati. Posizioni il logging all'esterno, seguito dalla convalida e poi dalle transazioni, in modo che ciascuno racchiuda correttamente il successivo.

services.AddTransient(typeof(IPipelineBehavior<,>), typeof(LoggingBehavior<,>));
services.AddTransient(typeof(IPipelineBehavior<,>), typeof(ValidationBehavior<,>));
services.AddTransient(typeof(IPipelineBehavior<,>), typeof(TransactionBehavior<,>));

Un comportamento transazionale

Racchiuda gli handler dei comandi in una transazione del database, così che l'intera operazione venga sottoposta a commit o rollback in modo atomico.

await using var tx = await _db.Database.BeginTransactionAsync(ct);
try
{
    var response = await next();
    await tx.CommitAsync(ct);
    return response;
}
catch
{
    await tx.RollbackAsync(ct);
    throw;
}

Applicazione a richieste specifiche

Utilizzi un'interfaccia marcatore e un vincolo generico affinché un comportamento venga applicato solo alle richieste che lo prevedono; ad esempio, solo i comandi ricevono le transazioni.

public interface ITransactional { }
public record CreateOrderCommand(...) : IRequest<int>, ITransactional;

// where TRequest : ITransactional

Perché i comportamenti sono preferibili al middleware

A differenza del middleware HTTP, i comportamenti vengono eseguiti per messaggio, dispongono della richiesta e della risposta tipizzate e funzionano anche quando una richiesta viene inviata al di fuori di HTTP (ad esempio da un processo in background).

// Strongly typed, transport-independent cross-cutting logic

Verifica rapida

Verifichi il funzionamento dei comportamenti.

Riepilogo

Ha appreso i comportamenti della pipeline:

  • IPipelineBehavior<TRequest, TResponse> racchiude ogni richiesta in una logica condivisa.
  • Il delegato next fa avanzare la pipeline; non chiamarlo interrompe anticipatamente l'handler.
  • Usi comuni: logging, convalida, transazioni e caching.
  • I comportamenti vengono eseguiti nell'ordine di registrazione e sono fortemente tipizzati.

Prossimo argomento: notifiche ed eventi.

Domande Frequenti

La lezione «Comportamenti della pipeline» è gratuita?

Sì — il testo completo di «Comportamenti della pipeline» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso C# Academy, passa a CoddyKit PRO. Il corso C# Academy include 4 lezioni in totale.

Cosa imparerò in «Comportamenti della pipeline»?

Aggiunga logica trasversale con i behaviors. Eserciti C# Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare C# Academy?

Non è richiesta alcuna esperienza precedente. C# Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 3 di 4.

Quanto tempo richiede la lezione «Comportamenti della pipeline»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione C# Academy?

Sì. Ogni lezione C# Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Concetti di CQRS
  2. Comandi e gestori con MediatR
  3. Comportamenti della pipeline
  4. Notifiche ed eventi
← Torna a C# Academy