イベントソーシングのコアコンセプト
イベントソーシングは、現代のソフトウェアアーキテクチャ、特にC#と.NET Coreアプリケーションで頻繁に使用される強力かつ複雑なパターンです。 イベント ソーシングの実装方法を完全に把握するために、CodeOpinion.com の Derek Comartin 氏がビデオ "Event Sourcing Core Concepts" で説明している主要な原則を順を追って説明します。
イベント・ストアのコンセプト、ドメイン駆動設計、イベント・ソース・システムの構築方法について理解を深めたいとお考えなら、この翻訳が最適です。 では、始めましょう!
イベント ソーシング入門
冒頭(0:00)で、デレクはイベント・ソーシングと関連するコア・コンセプトにまつわる混乱について説明します。彼はイベント・ソーシングを"現在の状態をキャプチャする"だけでなく、イベントを保存すること、つまりドメイン・モデルに起こるすべての変更を追記のみのログにキャプチャすることだと定義している。
こうすることで、システムの状態変化の完全な履歴を維持することができます。 最終的な状態だけを永続化するのではなく、発生したビジネスロジックを反映したイベントを永続化します。
イベント:ビジネスの事実を把握する
0:33では、デレクがイベントとは何かを説明しています。 イベントは、システム内ですでに発生したこと、つまりビジネス上の事実を表します。 例えば、"ProductReceived "イベントには、受け取った数量と日付が含まれます。
Derekは、イベントを保存するときは、"Product Shipped "や "Inventory Adjusted "のように、過去形を反映した命名規則を使って命名しなければならないと強調しています。 イベントスキーマには、public Guid Id、public string Name、タイムスタンプなどのフィールドがあります。

また、各イベントには一意の識別子が必要です。これは、イベントをイベントストリームに追加する、追加のみのストレージシステムにとって重要です。
イベントストリーム:イベントの整理
2:02、デレクはイベント・ストリームに移行する。 彼は、リレーショナルデータベースのテーブルとの比較を描いていますが、イベントソーシングでは、ドメインオブジェクト(在庫アイテムなど)に関連するすべてのイベントは、同じイベントストリームに属していると説明しています。
各イベント・ストリームは、特定のエンティティ(多くの場合、パブリックなGuid Idと文字列Nameで定義される)に関連付けられます。 例えば、SKU ABC123の製品は、受信や出荷のような永続化されたイベントを含む独自のストリームを持っています。
Derekは、これらをモデル化するとき、ドメイン駆動設計の概念を借りて、集約根とドメイン・オブジェクトの観点から考えることを提案する。
短命か長命かを問わず、ライフサイクルをモデル化することは、ストリームの数とサイズを最適化するのに役立ちます。 これは、複雑なシステムのパフォーマンスを向上させるために非常に重要です。
投影と読み取りモデル
4:12で、デレクはプロジェクションとリードモデルを紹介する。 イベント・ソース・システムは、現在の状態だけでなくイベントもキャプチャするため、"現在の在庫数量は?"といった質問に答えるためにイベントを再生する必要があります。
読み取りモデルを構築するには、ストリームからのイベントを処理します。 例えば、private void Apply(Event e)などを使って、各イベント・タイプのイベント・ハンドラに基づいて、ストックを増やしたり減らしたりします。
Derekは、文書データベースやリレーショナルデータベースで読み取りモデルを構築する方法を説明します。おそらく、あるプロジェクションは単に手持ちの数量を示し、別のプロジェクションは出荷履歴を示します。
これは、コマンド・クエリ責任分離(CQRS):書き込み操作(コマンド)と読み取り操作(クエリ)を分離することを反映しています。
書き込みモデルの予測
6:48で、デレクは書く側にもプロジェクションを適用する方法を示している。 これは、動作が許可される前に検証するために非常に重要です。
コマンドハンドラでは、製品を出荷する前に、十分な数量が存在することを確認する必要があります。 Derekは、private void Apply(List
public int Versionのようなフィールドは、ストリームの進化を追跡するのに役立ち、最終的な一貫性を保証します。

この実用的な実装は、新しいイベントを処理するときにビジネスロジックを強制するのに役立ち、システムが有効な状態遷移に対してのみ動作することを保証します。
サブスクリプション:新しいイベントに反応する
8:01で、デレクはサブスクリプションについて話しています。 サブスクリプションは、イベントコンシューマが新しいイベントをリッスンし、反応することを可能にします。
例えば、プロジェクターがイベントストリームをサブスクライブし、"Product Shipped "イベントを見たときにリードモデルを更新するような場合です。 また、パブリッシャーがイベントをリッスンし、RabbitMQやKafkaのような外部システムにパブリッシュし、他のサービスと統合することもあります。

Derekは、サブスクリプションについて、内部モデルを更新するためだけでなく、最終的な一貫性を維持しながら、別々のイベントシステム間でデータを配布するためにも説明しています。
これは、イベント駆動型アーキテクチャのもうひとつの大きな利点を示しています。
コア コンセプトのまとめ
9:21で、デレクが核となる概念を要約している:
イベントは事実を把握します。
イベントストリームは、エンティティごとにイベントを整理します。
プロジェクションは、ストリームをクエリ可能な読み取りモデルやアクション可能な書き込みモデルに変えます。
- サブスクリプションを利用することで、サービスに対応し、適宜更新することができます。
彼は、追記のみのログにイベントを永続化し、監査証跡を維持し、必要なときにイベントを再生することを強調している。
スナップショットと最適化
9:39で、Derekはスナップショットについて述べている。 イベント・ソーシングと並んで議論されることが多いが、スナップショットは中核的な要件ではなく、パフォーマンスの最適化であることを明確にしている。
スナップショットは、部分的な状態を定期的に保存することで、すべてのイベントを再生するオーバーヘッドを削減しますが、完全な履歴は、追加されたログのみによって存在します。
重要な違い:イベントソーシングとイベント駆動型アーキテクチャの比較
10:00、デレクはよくある誤解について警告する。イベント・ソーシングとイベント駆動アーキテクチャは異なる! Kafkaのようなツールはデータ配信に役立ちますが、真のイベントソーシングは、不変の監査証跡としてドメインイベントを記録することに重点を置いています。
イベントソーシングを複雑なシステムに統合するには、この違いを理解することが重要です。
結論
Derek Comartin氏のビデオを見ると、イベントソーシングとは、最終的な状態だけでなく、すべての変更をイベントとして記録することであることがわかります。 イベントをアペンドのみのストレージシステムに格納することで、監査証跡を提供するリッチなイベントスキーマを構築し、イベントをクエリするための柔軟性と、コマンドクエリの責任分離のための堅牢なサポートを提供します。
.NET Coreやその他のプラットフォームでC#イベントソーシングを扱っているかどうかにかかわらず、デレクのコアコンセプト、イベントハンドラ、プライベートセット、プロテクトセット、モデルでのprivate void Apply()のようなイベントの適用に関する構造化された説明は非常に価値があります。
弾力性のあるドメインモデルの構築、ストレージシステムの改善、あるいは最終的な一貫性のようないくつかの利点を持つ複雑なパターンの作成に取り組んでいるなら、Derek のアプローチを学ぶことは必須です。彼のYouTubeチャンネルで、より多くの洞察に満ちたビデオをご覧ください。

