C# Academy · Lektion

Pipeline behaviors

Tilføj tværgående logik med behaviors.

Lektion 3 af 413 trin

Pipeline behaviors er en gratis C# Academy-lektion på CoddyKit. Dette er lektion 3 af 4. Du kan læse hele lektionen gratis nedenfor — og derefter øve dig praktisk i browseren med en indbygget kodeeditor og en AI-vejleder, der er tilgængelig døgnet rundt. Den er en del af læringsforløbet i C# Academy, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. C# Academy-kurset indeholder 4 lektioner i alt.

Tværgående hensyn

Logning, validering, tidsmåling og transaktioner gælder for mange handlere. Hvis du kopierer den kode ind i hver handler, bliver det gentagende og fejlbehæftet.

MediatR's adfærd i behandlingskæden lader dig omslutte hver anmodning med fælles logik.

// One behavior runs around all handlers

IPipelineBehavior

En adfærd implementerer IPipelineBehavior<TRequest, TResponse>. Dens Handle-metode modtager anmodningen og en next-delegat, der kalder resten af behandlingskæden.

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

Den næste delegat

next() kalder den næste adfærd eller den faktiske handler, hvis dette er den sidste. Kode før kaldet kører på vejen ind; kode efter kaldet kører på vejen ud.

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

En logningsadfærd

En konkret logningsadfærd registrerer anmodningens navn på vejen ind og den forløbne tid på vejen ud.

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

Registrering af en adfærd

Registrér den åbent generiske adfærd i DI. MediatR anvender den på hver anmodning.

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

En valideringsadfærd

En populær anvendelse er validering af anmodninger med FluentValidation. Adfærden kører alle validatorer, før handleren udføres, og kaster en fejl, hvis nogen fejler.

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

Kortslutning

En adfærd kan springe handleren helt over ved at returnere uden at kalde next() – det er nyttigt til cachelagring af forespørgselsresultater eller afvisning af ugyldige anmodninger.

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

Rækkefølge for adfærd

Adfærd udføres i den rækkefølge, den registreres i. Placér logning yderst, derefter validering og så transaktioner, så hver del omslutter den næste korrekt.

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

En transaktionsadfærd

Omlæg kommandohandlere til en databasetransaktion, så hele handlingen enten gennemføres eller rulles tilbage atomisk.

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

Målretning mod bestemte anmodninger

Brug en markeringsgrænseflade og en generisk begrænsning, så en adfærd kun gælder for anmodninger, der tilvælger den – f.eks. så kun kommandoer får transaktioner.

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

// where TRequest : ITransactional

Hvorfor adfærd er bedre end middleware

I modsætning til HTTP-middleware kører adfærd pr. meddelelse, har den typede anmodning og det typede svar og fungerer også, når en anmodning sendes uden for HTTP (f.eks. fra et baggrundsjob).

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

Hurtigt tjek

Bekræft, hvordan adfærd fungerer.

Opsummering

Du har lært om adfærd i behandlingskæden:

  • IPipelineBehavior<TRequest, TResponse> omslutter hver anmodning med fælles logik.
  • next-delegaten fører behandlingskæden videre; hvis den springes over, kortsluttes handleren.
  • Almindelige anvendelser er logning, validering, transaktioner og cachelagring.
  • Adfærd kører i registreringsrækkefølgen og er stærkt typet.

Næste emne: meddelelser og hændelser.

Gratis at komme i gang

Lær C# med en AI-underviser — gratis

Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.

Kurser
93
Lektioner
346

Ofte stillede spørgsmål

Er lektionen “Pipeline behaviors” gratis?

Ja — hele teksten til “Pipeline behaviors” kan læses gratis her på nettet. Hvis du vil øve dig interaktivt med en indbygget kodeeditor og en AI-vejleder døgnet rundt og få adgang til resten af C# Academy-kurset, skal du opgradere til CoddyKit PRO. C# Academy-kurset indeholder 4 lektioner i alt.

Hvad lærer jeg i “Pipeline behaviors”?

Tilføj tværgående logik med behaviors. Du øver dig i C# Academy med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.

Skal jeg have erfaring for at begynde på C# Academy?

Der kræves ingen tidligere erfaring. C# Academy på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 3 af 4.

Hvor lang tid tager lektionen “Pipeline behaviors”?

De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.

Kan jeg skrive og køre kode i denne C# Academy-lektion?

Ja. Alle C# Academy-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.

Alle lektioner i dette kursus

  1. CQRS-koncepter
  2. Commands og handlers med MediatR
  3. Pipeline behaviors
  4. Notifikationer og events
← Tilbage til C# Academy