C# Academy · Oppitunti

Käsittelyputken toiminnat

Lisätkää poikkileikkaavaa logiikkaa toimintojen avulla.

Oppitunti 3/413 vaihetta

Käsittelyputken toiminnat on ilmainen C# Academy-oppitunti CoddyKitissä. Tämä on oppitunti 3/4. Voit lukea koko oppitunnin alta ilmaiseksi ja harjoitella sen jälkeen käytännössä selaimessa sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla. Oppitunti kuuluu C# Academy-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. C# Academy-kurssilla on yhteensä 4 oppituntia.

Poikkileikkaavat huolenaiheet

Lokitus, validointi, ajoitus ja transaktiot koskevat monia käsittelijöitä. Tällaisen koodin kopioiminen jokaiseen käsittelijään on toisteista ja altistaa virheille.

MediatR:n pipeline-toiminnot mahdollistavat jokaisen pyynnön ympäröimisen yhteisellä logiikalla.

// One behavior runs around all handlers

IPipelineBehavior

Toiminto toteuttaa IPipelineBehavior<TRequest, TResponse>-rajapinnan. Sen Handle-metodi vastaanottaa pyynnön ja next-delegaattifunktion, joka kutsuu putken loppuosaa.

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

Next-delegaatti

next() kutsuu seuraavaa toimintoa tai varsinaista käsittelijää, jos kyseessä on viimeinen toiminto. Kutsua edeltävä koodi suoritetaan menomatkalla ja kutsua seuraava koodi paluumatkalla.

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

Lokitustoiminto

Konkreettinen lokitustoiminto kirjaa pyynnön nimen menomatkalla ja kuluneen ajan paluumatkalla.

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

Toiminnon rekisteröinti

Rekisteröi avoin geneerinen toiminto DI:hin. MediatR soveltaa sitä jokaiseen pyyntöön.

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

Validointitoiminto

Yksi yleinen käyttötapaus on pyyntöjen validointi FluentValidationin avulla. Toiminto suorittaa kaikki validoijat ennen käsittelijää ja heittää poikkeuksen, jos jokin validointi epäonnistuu.

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

Suorituksen ohittaminen

Toiminto voi ohittaa käsittelijän kokonaan palauttamalla tuloksen kutsumatta next()-funktiota. Tämä on hyödyllistä esimerkiksi kyselytulosten välimuistituksessa tai virheellisten pyyntöjen hylkäämisessä.

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

Toimintojen järjestys

Toiminnot suoritetaan siinä järjestyksessä, jossa ne on rekisteröity. Sijoita lokitus uloimmaksi, sen jälkeen validointi ja sitten transaktiot, jotta kukin toiminto ympäröi seuraavan oikein.

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

Transaktiotoiminto

Ympäröi komentojen käsittelijät tietokantatransaktiolla, jotta koko toiminto joko vahvistetaan tai peruutetaan yhtenäisesti.

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

Tiettyjen pyyntöjen kohdentaminen

Käytä merkintärajapintaa ja geneeristä rajoitetta, jotta toiminto koskee vain pyyntöjä, jotka ovat ottaneet sen käyttöön. Voit esimerkiksi kohdistaa transaktiot vain komentoihin.

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

// where TRequest : ITransactional

Miksi toiminnot ovat parempia kuin middleware

Toisin kuin HTTP-middleware, toiminnot suoritetaan viestikohtaisesti, niillä on tyypitetty pyyntö ja vastaus, ja ne toimivat myös silloin, kun pyyntö välitetään HTTP:n ulkopuolelta, esimerkiksi taustatyöstä.

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

Pikatarkistus

Varmista, että ymmärrät toimintojen toimintaperiaatteen.

Kertaus

Opitte pipeline-toiminnot:

  • IPipelineBehavior<TRequest, TResponse> ympäröi jokaisen pyynnön yhteisellä logiikalla.
  • next-delegaatti siirtää käsittelyä putkessa eteenpäin; sen ohittaminen estää käsittelijän suorituksen.
  • Yleisiä käyttötapauksia ovat lokitus, validointi, transaktiot ja välimuistitus.
  • Toiminnot suoritetaan rekisteröintijärjestyksessä ja ne ovat vahvasti tyypitettyjä.

Seuraavaksi käsitellään ilmoituksia ja tapahtumia.

Aloita maksutta

Opi C# tekoälytuutorin avulla — ilmaiseksi

Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.

Kurssit
93
Oppitunnit
346

Usein kysytyt kysymykset

Onko oppitunti ”Käsittelyputken toiminnat” ilmainen?

Kyllä – oppitunnin ”Käsittelyputken toiminnat” koko tekstin voi lukea täällä verkossa ilmaiseksi. Jos haluat harjoitella interaktiivisesti sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla sekä avata koko C# Academy-kurssin, päivitä CoddyKit PROhon. C# Academy-kurssilla on yhteensä 4 oppituntia.

Mitä opin oppitunnilla ”Käsittelyputken toiminnat”?

Lisätkää poikkileikkaavaa logiikkaa toimintojen avulla. Harjoittelet C# Academy-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.

Tarvitsenko kokemusta aloittaakseni C# Academy-opiskelun?

Aiempi kokemus ei ole tarpeen. CoddyKitin C# Academy-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 3/4.

Kuinka kauan ”Käsittelyputken toiminnat”-oppitunnin suorittaminen kestää?

Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.

Voinko kirjoittaa ja suorittaa koodia tällä C# Academy-oppitunnilla?

Kyllä. Jokainen C# Academy-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.

Kaikki tämän kurssin oppitunnit

  1. CQRS:n käsitteet
  2. Komennot ja käsittelijät MediatR:llä
  3. Käsittelyputken toiminnat
  4. Ilmoitukset ja tapahtumat
← Takaisin: C# Academy