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 handlersIPipelineBehavior
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 : ITransactionalPerché 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 logicVerifica 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
nextfa 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
- Concetti di CQRS
- Comandi e gestori con MediatR
- Comportamenti della pipeline
- Notifiche ed eventi