我正在開發一個event-sourced CQRS實現,在應用程序/域中使用DDD。我有一個看起來像這樣的對象模型:事件源聚合根可以訪問事件採購存儲庫嗎?
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的瞭解,到目前爲止,個人和預訂兩種原因有兩個單獨的總根源:
- 有些時候,業務組件會將預訂對象與數據庫分開。 (即,由於信息不正確,已發佈的人員之前的預訂已被修改)。
- 無論何時預訂需要更新,Person和Booking之間不應該存在鎖定爭用。
另一個業務需求是,一次預訂永遠不會發生一次。由於這一點,我擔心查詢查詢數據庫在讀取方面,因爲可能會有一些不一致(由於使用CQRS並具有最終一致的讀取數據庫)。
是否應該允許聚合根據對象(根據需要延遲加載它們)通過id的事件源後備存儲查詢?是否還有其他更有意義的實施途徑?
「公衆人物(識別標識) { 應用(新PersonCreatedEvent(標識));} 」如果你正在構建從內存中的對象會發生什麼,你不是創建一個新的人,但你將發佈一個新的事件。我喜歡你定義事件處理程序的方式。所以知道一個對象的狀態只能在將一個命令應用到一個存儲庫時才能改變,也許你應該添加命令處理程序,除非你要完全基於事件,恕我直言並沒有多大意義。 – Marco 2013-08-12 14:25:36
我無法弄清楚爲什麼你要處理一個你自己的倉庫應該發佈的事件? 「BookingCreatedEvent」 – Marco 2013-08-12 14:31:25