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

คำสั่งและตัวจัดการด้วย MediatR

ส่งคำขอไปยังตัวจัดการเฉพาะทาง

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

การลงทะเบียน MediatR

MediatR จะสแกนแอสเซมบลีของคุณเพื่อค้นหา handler ให้ลงทะเบียนครั้งเดียวตอนเริ่มต้นระบบ โดยระบุแอสเซมบลีที่มี handler ของคุณ

builder.Services.AddMediatR(cfg =>
    cfg.RegisterServicesFromAssembly(typeof(Program).Assembly));

อินเทอร์เฟซคำขอ

ข้อความที่คาดว่าจะได้รับการตอบกลับจะใช้งาน IRequest<TResponse> พารามิเตอร์ชนิดข้อมูลคือค่าที่ handler ส่งคืน

public record CreateOrderCommand(int CustomerId, string[] Items)
    : IRequest<int>;   // returns the new order id

คำสั่งที่ไม่มีผลลัพธ์

หากคำสั่งไม่ส่งคืนสิ่งที่มีความหมาย ให้ใช้งาน IRequest ที่ไม่มีพารามิเตอร์ชนิดข้อมูล ซึ่งเป็นรูปย่อของ IRequest<Unit>

public record CancelOrderCommand(int OrderId) : IRequest;

อินเทอร์เฟซตัวจัดการคำขอ

handler ใช้งาน IRequestHandler<TRequest, TResponse> และจัดเตรียมเมธอด Handle ซึ่งเป็นจุดที่งานจะเกิดขึ้น

public class CreateOrderHandler
    : IRequestHandler<CreateOrderCommand, int>
{
    public Task<int> Handle(
        CreateOrderCommand request, CancellationToken ct)
    {
        // create the order...
        return Task.FromResult(newOrderId);
    }
}

การฉีดการพึ่งพา

ระบบจะแก้ไข handler จาก DI ดังนั้น handler จึงสามารถรับ context ของฐานข้อมูล ที่เก็บข้อมูล หรือบริการอื่น ๆ ผ่านตัวสร้างได้

public class CreateOrderHandler(AppDbContext db)
    : IRequestHandler<CreateOrderCommand, int>
{
    public async Task<int> Handle(
        CreateOrderCommand request, CancellationToken ct)
    {
        var order = new Order { CustomerId = request.CustomerId };
        db.Orders.Add(order);
        await db.SaveChangesAsync(ct);
        return order.Id;
    }
}

ตัวส่งคำขอ

หากต้องการส่งต่อคำขอ ให้ฉีด ISender หรือ IMediator ที่ครอบคลุมกว่า แล้วเรียก Send MediatR จะค้นหา handler ที่ตรงกัน

public class OrdersController(ISender sender) : ControllerBase
{
    [HttpPost]
    public async Task<IActionResult> Create(CreateOrderCommand cmd)
    {
        int id = await sender.Send(cmd);
        return CreatedAtAction(nameof(Get), new { id }, null);
    }
}

การใช้ Send ใน API แบบย่อ

API แบบย่อจะฉีด ISender เข้าไปในตัวมอบหมายของจุดปลายทางโดยตรง

app.MapPost("/orders", async (
    CreateOrderCommand cmd, ISender sender) =>
{
    var id = await sender.Send(cmd);
    return Results.Created($"/orders/{id}", new { id });
});

คิวรีก็คือคำขอ

คิวรีใช้กลไก IRequest / IRequestHandler เดียวกัน ความแตกต่างเพียงอย่างเดียวคือเจตนา: handler จะอ่านข้อมูลและไม่เปลี่ยนแปลงข้อมูล

public record GetOrderQuery(int Id) : IRequest<OrderDto?>;

public class GetOrderHandler(AppDbContext db)
    : IRequestHandler<GetOrderQuery, OrderDto?>
{
    public async Task<OrderDto?> Handle(
        GetOrderQuery q, CancellationToken ct) =>
        await db.Orders
            .Where(o => o.Id == q.Id)
            .Select(o => new OrderDto(o.Id, o.Total))
            .SingleOrDefaultAsync(ct);
}

หนึ่ง Handler ต่อหนึ่งคำขอ

สำหรับ Send จะต้องมี handler ที่ตรงกับชนิดคำขอ เพียงหนึ่งรายการ เท่านั้น การลงทะเบียน handler เป็นศูนย์หรือสองรายการสำหรับคำขอเดียวกันถือเป็นข้อผิดพลาดในการตั้งค่า

// CreateOrderCommand -> exactly one CreateOrderHandler

การส่งคืนผลลัพธ์ที่มีรายละเอียด

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

public record Result(bool Ok, string? Error);
public record PlaceOrderCommand(int Id) : IRequest<Result>;

การทดสอบ Handler

เนื่องจาก handler เป็นคลาสธรรมดาที่มีการฉีดการพึ่งพา คุณจึงทดสอบได้โดยตรง โดยไม่ต้องใช้ HTTP หรือคอนโทรลเลอร์

var handler = new CreateOrderHandler(inMemoryDb);
var id = await handler.Handle(
    new CreateOrderCommand(1, ["sku-1"]), CancellationToken.None);
Assert.True(id > 0);

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

ยืนยันรูปแบบการส่งต่อของ MediatR

สรุป

คุณได้พัฒนาคำสั่งและ handler ดังนี้:

  • AddMediatR สแกนแอสเซมบลีเพื่อลงทะเบียน handler
  • ข้อความใช้งาน IRequest<T> ส่วน handler ใช้งาน IRequestHandler<TRequest, T>
  • ฉีด ISender แล้วเรียก Send เพื่อส่งต่อคำขอ โดยจะมี handler ที่ตรงกันเพียงหนึ่งรายการ
  • คิวรีใช้กลไกเดียวกันและไม่มีผลข้างเคียง

ถัดไป: พฤติกรรมไปป์ไลน์

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

บทเรียน “คำสั่งและตัวจัดการด้วย MediatR” ฟรีหรือไม่

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

คุณจะเรียนรู้อะไรในบทเรียน “คำสั่งและตัวจัดการด้วย MediatR”

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

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

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

บทเรียน “คำสั่งและตัวจัดการด้วย MediatR” ใช้เวลานานแค่ไหน

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

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

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

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

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