イベントソースの集計ルートは、イベント調達リポジトリにアクセスできる必要がありますか?

StackOverflow https://stackoverflow.com/questions/2906370

質問

私はに取り組んでいます イベントソース アプリケーション /ドメインレイヤーでDDDを使用したCQRS実装。私は次のように見えるオブジェクトモデルを持っています:

public class Person : AggregateRootBase
{
    private Guid? _bookingId;

    public Person(Identification identification)
    {
        Apply(new PersonCreatedEvent(identification));
    }

    public Booking CreateBooking() {
        // Enforce Person invariants
        var booking = new Booking();
        Apply(new PersonBookedEvent(booking.Id));
        return booking;
    }

    public void Release() {
        // Enforce Person invariants
        // Should we load the booking here from the aggregate repository?
        // We need to ensure that booking is released as well.
        var booking = BookingRepository.Load(_bookingId);
        booking.Release();
        Apply(new PersonReleasedEvent(_bookingId));
    }

    [EventHandler]
    public void Handle(PersonBookedEvent @event) { _bookingId = @event.BookingId; }

    [EventHandler]
    public void Handle(PersonReleasedEvent @event) { _bookingId = null; }
}

public class Booking : AggregateRootBase
{
    private DateTime _bookingDate;
    private DateTime? _releaseDate;

    public Booking()
    {
        //Enforce invariants
        Apply(new BookingCreatedEvent());
    }

    public void Release() 
    {
        //Enforce invariants
        Apply(new BookingReleasedEvent());
    }

    [EventHandler]
    public void Handle(BookingCreatedEvent @event) { _bookingDate = SystemTime.Now(); }
    [EventHandler]
    public void Handle(BookingReleasedEvent @event) { _releaseDate = SystemTime.Now(); }
    // Some other business activities unrelated to a person
}

これまでのDDDを理解しているため、人と予約の両方が2つの理由で総根の個別です。

  1. ビジネスコンポーネントがデータベースとは別に予約オブジェクトをプルする場合があります。 (つまり、釈放された人は、誤った情報のために以前の予約が変更されました)。
  2. 予約を更新する必要があるときはいつでも、人と予約の間にロック競合があるべきではありません。

もう1つのビジネス要件は、人に一度に2回以上予約が行われることはないことです。このため、読み取り側のクエリデータベースのクエリを照会することは心配しています(CQRを使用し、最終的に一貫した読み取りデータベースがあるため)、ある程度の矛盾がある可能性があるためです。

集計ルートは、オブジェクトのIDでイベントソースのバッキングストアをクエリすることができますか(必要に応じて怠zy-ロード)?より理にかなっている実装の他の手段はありますか?

役に立ちましたか?

解決

まず第一に、あなたは本当にあなたのケースで本当にイベントの調達が必要ですか?私にはとても簡単に見えます。イベントソーシングには、利点と短所の両方があります。無料の監査証跡を提供し、ドメインモデルをより表現力豊かにしますが、ソリューションを複雑にします。

わかりました、この時点であなたはあなたの決定を考え、あなたはイベント調達にとどまることを決心していると思います。凝集体間のコミュニケーション手段としてのメッセージングの概念が欠けていると思います。で最もよく説明されています パット・ヘランドの論文 (ところで、DDDやイベントの調達についてではなく、スケーラビリティに関する)。

アイデアは、集計が互いにメッセージを送信して、何らかの行動を強制することです。集合体間の同期(別名メソッド呼び出し)相互作用はあり得ません。これにより、一貫性の問題が発生するためです。

あなたの例では、人は予約メッセージを予約ARに送信します。このメッセージは、非同期で信頼できる方法で輸送されます。 ARの予約はこのメッセージを処理し、他の人がすでに予約している場合は、Reservation Rejectedメッセージで返信します。それ以外の場合は、予約済みを送信します。これらのメッセージは、人ARによって処理する必要があります。おそらく、彼らはさらに別のイベントを生成し、顧客またはそのようなものに送信される電子メールに変換されます。

モデルにクエリデータを取得する必要はありません。ただメッセージング。例が必要な場合は、の「メッセージング」ブランチのソースをダウンロードできます NCQRS プロジェクトとシナリオテストクラスをご覧ください。 Blue Bookの貨物とHondlingEventサンプルを使用してARS間のメッセージングを示しています。

これはあなたの質問に答えますか?

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top