C# Academy · Aula

Comportamentos de pipeline

Adicione lógica transversal com comportamentos.

Aula 3 de 413 etapas

Comportamentos de pipeline é uma aula grátis de C# Academy no CoddyKit. Esta é a aula 3 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de C# Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de C# Academy inclui 4 aulas no total.

Preocupações transversais

Registro, validação, medição de tempo e transações se aplicam a muitos handlers. Copiar esse código para cada handler é repetitivo e propenso a erros.

Os comportamentos do canal de processamento do MediatR permitem envolver cada solicitação com lógica compartilhada.

// One behavior runs around all handlers

Comportamento do canal de processamento

Um comportamento implementa IPipelineBehavior<TRequest, TResponse>. Seu método Handle recebe a solicitação e um delegado next que invoca o restante do canal de processamento.

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;
    }
}

O delegado seguinte

next() chama o comportamento seguinte ou o handler real se este for o último. O código antes da chamada é executado durante a entrada; o código depois é executado durante a saída.

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

Um comportamento de registro

Um comportamento concreto de registro anota o nome da solicitação durante a entrada e o tempo decorrido durante a saída.

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;
}

Registrando um comportamento

Registre o comportamento genérico aberto em DI. O MediatR o aplica a todas as solicitações.

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

Um comportamento de validação

Um uso comum é validar solicitações com FluentValidation. O comportamento executa todos os validadores antes que o handler seja executado e lança uma exceção se algum deles falhar.

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();
}

Interrupção antecipada

Um comportamento pode ignorar completamente o handler retornando sem chamar next() — algo útil para armazenar resultados de consultas em cache ou rejeitar solicitações inválidas.

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

Ordenando comportamentos

Os comportamentos são executados na ordem em que foram registrados. Coloque o registro na camada mais externa, depois a validação e, em seguida, as transações, para que cada um envolva corretamente o próximo.

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

Um comportamento de transação

Envolva os handlers de comandos em uma transação de banco de dados para que toda a operação seja confirmada ou revertida atomicamente.

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;
}

Direcionando solicitações específicas

Use uma interface marcadora e uma restrição genérica para que um comportamento se aplique apenas às solicitações que optarem por ele — por exemplo, somente os comandos recebem transações.

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

// where TRequest : ITransactional

Por que os comportamentos superam o intermediário HTTP

Ao contrário do intermediário HTTP, os comportamentos são executados por mensagem, recebem a solicitação e a resposta tipadas e funcionam mesmo quando uma solicitação é encaminhada fora do HTTP, por exemplo, a partir de uma tarefa em segundo plano.

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

Verificação rápida

Confirme como os comportamentos funcionam.

Recapitulação

Você aprendeu sobre os comportamentos do canal de processamento:

  • IPipelineBehavior<TRequest, TResponse> envolve cada solicitação com lógica compartilhada.
  • O delegado next avança pelo canal de processamento; ignorá-lo interrompe o handler.
  • Usos comuns: registro, validação, transações e armazenamento em cache.
  • Os comportamentos são executados na ordem de registro e são fortemente tipados.

Próximo tópico: notificações e eventos.

Grátis para começar

Aprenda C# com um tutor de IA — grátis

Escreva e execute código real no seu navegador, obtenha ajuda instantânea de um tutor de IA 24/7 e continue de onde parou na web ou no app.

Cursos
93
Aulas
346

Perguntas Frequentes

A aula “Comportamentos de pipeline” é grátis?

Sim — o texto completo de “Comportamentos de pipeline” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de C# Academy, atualize para CoddyKit PRO. O curso de C# Academy inclui 4 aulas no total.

O que vou aprender em “Comportamentos de pipeline”?

Adicione lógica transversal com comportamentos. Você pratica C# Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar C# Academy?

Nenhuma experiência prévia é necessária. C# Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 3 de 4.

Quanto tempo leva a aula “Comportamentos de pipeline”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de C# Academy?

Sim. Cada aula de C# Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. Conceitos de CQRS
  2. Comandos e manipuladores com MediatR
  3. Comportamentos de pipeline
  4. Notificações e eventos
← Voltar para C# Academy