0Pricing
C# Academy · บทเรียน

พฤติกรรมของไปป์ไลน์

เพิ่มตรรกะที่ใช้ร่วมกันหลายส่วนด้วยพฤติกรรม

พฤติกรรมของไปป์ไลน์ เป็นบทเรียน C# Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน C# Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส C# Academy มีบทเรียนทั้งหมด 4 บทเรียน

ประเด็นข้ามส่วน

การบันทึกล็อก การตรวจสอบความถูกต้อง การจับเวลา และธุรกรรม ล้วนใช้กับ handler หลายรายการ การคัดลอกโค้ดเหล่านี้ไปไว้ใน handler แต่ละตัวเป็นงานซ้ำซากและทำให้เกิดข้อผิดพลาดได้ง่าย

พฤติกรรมไปป์ไลน์ ของ MediatR ช่วยให้คุณครอบทุกคำขอด้วยตรรกะที่ใช้ร่วมกันได้

// One behavior runs around all handlers

IPipelineBehavior

พฤติกรรมหนึ่งจะใช้งาน IPipelineBehavior<TRequest, TResponse> เมธอด Handle ของพฤติกรรมจะได้รับคำขอและตัวมอบหมาย next ซึ่งเรียกใช้ส่วนที่เหลือของไปป์ไลน์

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() จะเรียกใช้พฤติกรรมถัดไป หรือเรียกใช้ handler จริงหากนี่เป็นพฤติกรรมสุดท้าย โค้ดที่อยู่ ก่อน การเรียกจะทำงานขณะคำขอเข้ามา ส่วนโค้ดที่อยู่ หลัง การเรียกจะทำงานขณะคำขอส่งกลับ

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

พฤติกรรมการบันทึกล็อก

พฤติกรรมการบันทึกล็อกที่ใช้งานจริงจะบันทึกชื่อคำขอขณะคำขอเข้ามา และบันทึกเวลาที่ผ่านไปขณะคำขอส่งกลับ

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

การลงทะเบียนพฤติกรรม

ลงทะเบียนพฤติกรรมแบบเจเนอริกเปิดใน DI MediatR จะนำพฤติกรรมนี้ไปใช้กับทุกคำขอ

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

พฤติกรรมการตรวจสอบความถูกต้อง

การใช้งานที่ได้รับความนิยมคือการตรวจสอบคำขอด้วย FluentValidation พฤติกรรมนี้จะเรียกใช้ตัวตรวจสอบทั้งหมดก่อนที่ handler จะทำงาน และโยนข้อผิดพลาดหากมีรายการใดไม่ผ่าน

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

การตัดการทำงานล่วงหน้า

พฤติกรรมสามารถ ข้ามการทำงานของ handler ทั้งหมด ได้โดยส่งคืนผลลัพธ์โดยไม่เรียก next() ซึ่งมีประโยชน์สำหรับการแคชผลลัพธ์ของคิวรีหรือการปฏิเสธคำขอที่ไม่ถูกต้อง

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

การจัดลำดับพฤติกรรม

พฤติกรรมจะทำงานตามลำดับที่ลงทะเบียนไว้ ให้การบันทึกล็อกอยู่ชั้นนอกสุด ตามด้วยการตรวจสอบความถูกต้อง แล้วจึงเป็นธุรกรรม เพื่อให้แต่ละรายการครอบรายการถัดไปได้อย่างถูกต้อง

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

พฤติกรรมธุรกรรม

ครอบ handler ของคำสั่งไว้ในธุรกรรมฐานข้อมูล เพื่อให้การดำเนินการทั้งหมดถูกยืนยันหรือย้อนกลับแบบเป็นหน่วยเดียวกัน

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

การกำหนดเป้าหมายให้คำขอบางรายการ

ใช้อินเทอร์เฟซเครื่องหมายและข้อจำกัดแบบเจเนอริก เพื่อให้พฤติกรรมมีผลเฉพาะกับคำขอที่เลือกใช้เท่านั้น เช่น ให้ธุรกรรมมีผลเฉพาะกับคำสั่ง

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

// where TRequest : ITransactional

เหตุใดพฤติกรรมจึงดีกว่ามิดเดิลแวร์

พฤติกรรมต่างจากมิดเดิลแวร์ HTTP ตรงที่ทำงานแบบ per ข้อความ มีคำขอและการตอบกลับที่ระบุชนิดข้อมูล และยังทำงานได้แม้คำขอจะถูกส่งออกนอก HTTP เช่น จากงานเบื้องหลัง

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

ตรวจสอบความเข้าใจอย่างรวดเร็ว

ยืนยันวิธีการทำงานของพฤติกรรม

สรุป

คุณได้เรียนรู้พฤติกรรมไปป์ไลน์ดังนี้:

  • IPipelineBehavior<TRequest, TResponse> ครอบทุกคำขอด้วยตรรกะที่ใช้ร่วมกัน
  • ตัวมอบหมาย next เลื่อนไปยังขั้นถัดไปของไปป์ไลน์ การข้ามตัวมอบหมายนี้จะตัดการทำงานของ handler ล่วงหน้า
  • การใช้งานทั่วไป ได้แก่ การบันทึกล็อก การตรวจสอบความถูกต้อง ธุรกรรม และการแคช
  • พฤติกรรมทำงานตามลำดับการลงทะเบียนและมีการระบุชนิดข้อมูลอย่างเคร่งครัด

ถัดไป: การแจ้งเตือนและเหตุการณ์

คำถามที่พบบ่อย

บทเรียน “พฤติกรรมของไปป์ไลน์” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “พฤติกรรมของไปป์ไลน์” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส C# Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส C# Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “พฤติกรรมของไปป์ไลน์”

เพิ่มตรรกะที่ใช้ร่วมกันหลายส่วนด้วยพฤติกรรม คุณปฏิบัติ C# Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน C# Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน C# Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน

บทเรียน “พฤติกรรมของไปป์ไลน์” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน C# Academy นี้ได้ไหม

ได้ บทเรียน C# Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. แนวคิด CQRS
  2. คำสั่งและตัวจัดการด้วย MediatR
  3. พฤติกรรมของไปป์ไลน์
  4. การแจ้งเตือนและเหตุการณ์
← กลับไปที่ C# Academy