0Pricing
C# Academy · レッスン

通知とイベント

MediatRでドメインイベントを発行します。

「通知とイベント」はCoddyKit上の無料C# Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはC# Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 C# Academyコースには全4レッスンが含まれています。

リクエストと通知の違い

リクエストには1 つのハンドラーがあり、値を返します。通知はブロードキャストであり、ハンドラーは0 個以上で、何も返しません。何かが起きたことを知らせるには、通知を使用します。

// 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> を実装します。1つの通知を複数のハンドラーが購読でき、それぞれが独立して処理します。

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

複数の購読者

必要な数だけハンドラーを追加できます。ハンドラー同士は互いを認識しないため、パブリッシャーに変更を加えずに新しい反応を追加できます。

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

発行

通知を発行するには、IPublisher(または IMediator)を依存性として注入し、Publish を呼び出します。登録されているすべてのハンドラーが呼び出されます。

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

副作用の分離

通知を使うと、主要なユースケースに集中できます。注文の作成では注文を記録してイベントを発行するだけにし、メール送信や在庫処理はそれぞれのハンドラーで行います。これは開放/閉鎖原則を実践したものです。

// CreateOrderHandler does NOT know about email or inventory

発行戦略

既定では、MediatR は各通知ハンドラーを順番に待機します。いずれかのハンドラーが例外をスローすると、それ以降のハンドラーは実行されません。カスタムパブリッシャーを指定して、ハンドラーを並列実行することもできます。

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

失敗への対応

ハンドラーは独立しているため、失敗をどのように扱うかを決めておく必要があります。重要度の低い副作用については、ハンドラー内で例外を捕捉してログに記録すると、1つの失敗が他のハンドラーに影響しません。

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

通知のテスト

モックの 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 は、0個以上の INotificationHandler にブロードキャストする仕組みです。
  • IPublisher.Publish で発行すると、すべての購読者が呼び出されます。
  • 通知によって副作用が分離され、開放/閉鎖原則に従うことができます。
  • 通知はインプロセスで処理されるため、サービス間通信や永続的なイベントにはブローカーを使用します。

CQRS と MediatR のコースはこれで完了です。

よくある質問

「通知とイベント」レッスンは無料ですか?

はい。「通知とイベント」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、C# Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 C# Academyコースには全4レッスンが含まれています。

「通知とイベント」で何を学びますか?

MediatRでドメインイベントを発行します。 ブラウザで直接実行するハンズオンコードでC# Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

C# Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのC# Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。

「通知とイベント」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このC# Academyレッスンでコードを書いて実行できますか?

はい。すべてのC# Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. CQRSの概念
  2. MediatRによるコマンドとハンドラー
  3. パイプラインビヘイビアー
  4. 通知とイベント
← C# Academyに戻る