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

การแจ้งเตือนและเหตุการณ์

เผยแพร่เหตุการณ์โดเมนด้วย MediatR

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

คำขอกับการแจ้งเตือน

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

// Request:      one handler, returns a result
// Notification: many handlers, fire-and-forget

INotification

เหตุการณ์โดเมนคือระเบียนที่ใช้งาน INotification โดยอธิบายข้อเท็จจริงที่เกิดขึ้นแล้วในรูปอดีตกาล

public record OrderPlacedNotification(int OrderId, int CustomerId)
    : INotification;

INotificationHandler

สมาชิกผู้รับแต่ละรายใช้งาน INotificationHandler<TNotification> สมาชิกผู้รับหลายรายสามารถสมัครรับการแจ้งเตือนเดียวกันได้ โดยแต่ละรายจะจัดการอย่างเป็นอิสระต่อกัน

public class SendConfirmationEmailHandler
    : INotificationHandler<OrderPlacedNotification>
{
    public Task Handle(
        OrderPlacedNotification n, CancellationToken ct)
    {
        // send the email...
        return Task.CompletedTask;
    }
}

สมาชิกผู้รับหลายราย

เพิ่ม handler ได้มากเท่าที่ต้องการ handler เหล่านี้ไม่รู้จักกัน จึงสามารถเพิ่มการตอบสนองรูปแบบใหม่ได้โดยไม่ต้องแก้ไข publisher

public class UpdateInventoryHandler
    : INotificationHandler<OrderPlacedNotification>
{
    public Task Handle(OrderPlacedNotification n, CancellationToken ct)
    {
        // decrement stock...
        return Task.CompletedTask;
    }
}

การเผยแพร่

หากต้องการส่งการแจ้งเตือน ให้ฉีด IPublisher (หรือ IMediator) แล้วเรียกใช้ Publish handler ที่ลงทะเบียนไว้ทุกตัวจะถูกเรียกใช้งาน

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

การแยกผลข้างเคียงออกจากกัน

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

// CreateOrderHandler does NOT know about email or inventory

กลยุทธ์การเผยแพร่

ตามค่าเริ่มต้น MediatR จะรอ handler ของการแจ้งเตือนแต่ละตัวตามลำดับ หากตัวใดตัวหนึ่งทำงานล้มเหลว handler ตัวถัดไปจะไม่ทำงาน คุณสามารถกำหนด publisher แบบกำหนดเองเพื่อให้ทำงานแบบขนานได้

builder.Services.AddMediatR(cfg =>
{
    cfg.RegisterServicesFromAssembly(typeof(Program).Assembly);
    cfg.NotificationPublisher = new TaskWhenAllPublisher();
});

การจัดการความล้มเหลว

เนื่องจาก handler ทำงานแยกจากกัน จึงควรกำหนดให้ชัดเจนว่าความล้มเหลวมีความหมายอย่างไร สำหรับผลข้างเคียงที่ไม่สำคัญ ให้ดักจับและบันทึกข้อมูลการทำงานภายใน handler เพื่อไม่ให้ความล้มเหลวหนึ่งรายการทำให้รายการอื่นหยุดทำงาน

public async Task Handle(OrderPlacedNotification n, CancellationToken ct)
{
    try { await _email.SendAsync(n.CustomerId, ct); }
    catch (Exception ex) { _logger.LogError(ex, "email failed"); }
}

รูปแบบเหตุการณ์โดเมน

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

await db.SaveChangesAsync(ct);
foreach (var domainEvent in order.Events)
    await publisher.Publish(domainEvent, ct);
order.Events.Clear();

การแจ้งเตือนกับคิวข้อความ

การแจ้งเตือนของ MediatR ทำงาน ภายในกระบวนการ และเป็นแบบซิงโครนัสภายในคำขอ สำหรับการสื่อสารข้ามบริการหรือการส่งมอบที่ต้องคงอยู่ ให้เผยแพร่ไปยังตัวกลางรับส่งข้อความจริง เช่น RabbitMQ หรือ Azure Service Bus แทน

// In-process reactions  -> MediatR notifications
// Cross-service / durable -> message broker

การทดสอบการแจ้งเตือน

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

var publisher = new Mock<IPublisher>();
var handler = new CreateOrderHandler(db, publisher.Object);
await handler.Handle(new CreateOrderCommand(1, []), default);
publisher.Verify(p => p.Publish(
    It.IsAny<OrderPlacedNotification>(), default), Times.Once);

ตรวจสอบความเข้าใจ

ยืนยันความเข้าใจเกี่ยวกับรูปแบบการแจ้งเตือน

สรุปทบทวน

คุณได้เรียนรู้เกี่ยวกับการแจ้งเตือนและเหตุการณ์ดังนี้:

  • INotification คือการกระจายข้อความที่มี INotificationHandler ได้ตั้งแต่ศูนย์รายการขึ้นไป
  • เผยแพร่ด้วย IPublisher.Publish เพื่อเรียกใช้งานสมาชิกผู้รับทั้งหมด
  • การแจ้งเตือนช่วยแยกผลข้างเคียงออกจากกัน และเป็นไปตามหลักการเปิด/ปิด
  • การแจ้งเตือนทำงานภายในกระบวนการ หากต้องการเหตุการณ์ข้ามบริการหรือเหตุการณ์ที่ต้องคงอยู่ ให้ใช้ตัวกลางรับส่งข้อความ

หลักสูตร CQRS และ MediatR จบลงเพียงเท่านี้

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

บทเรียน “การแจ้งเตือนและเหตุการณ์” ฟรีหรือไม่

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

คุณจะเรียนรู้อะไรในบทเรียน “การแจ้งเตือนและเหตุการณ์”

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

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

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

บทเรียน “การแจ้งเตือนและเหตุการณ์” ใช้เวลานานแค่ไหน

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

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

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

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

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