Estoy trabajando en una implementación de CQRS event-sourced, usando DDD en la capa de aplicación/dominio. Tengo un modelo de objetos que tiene este aspecto:¿Debe una raíz agregada de orígenes de eventos tener acceso al repositorio de abastecimiento de eventos?
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
}
Con mi comprensión de DDD hasta ahora, tanto en persona y reserva son raíces agregados separados por dos razones:
- hay momentos en los componentes de negocio se extraiga los objetos de Booking por separado de la base de datos. (es decir, una persona que ha sido liberada tiene una reserva previa modificada debido a información incorrecta).
- No debe existir conflicto de bloqueo entre Persona y Reserva cada vez que se necesite actualizar una Reserva.
Otro requisito comercial es que una Reservación nunca puede ocurrir para una Persona más de una vez a la vez. Debido a esto, me preocupa consultar la base de datos de consulta en el lado de lectura, ya que podría existir una cierta incoherencia allí (debido al uso de CQRS y tener una base de datos de lectura eventualmente consistente).
¿Se les debe permitir a las raíces agregadas consultar el almacén de respaldo del origen del evento por id para los objetos (cargarlos de forma diferida según sea necesario)? ¿Hay otras vías de implementación que tengan más sentido?
"Persona pública (identificación de Identificación) { Aplicar (nueva PersonCreatedEvent (identificación));} " qué sucede si usted está construyendo el objeto de la memoria, no se va a crear una nueva persona, sino que será la publicación un nuevo evento. Me gusta la forma en que defines los controladores de eventos.Entonces, sabiendo que el estado de un objeto solo puede cambiar al aplicar un comando a un repositorio, quizás también deba agregar controladores de comando, a menos que esté basado en un evento completo, que en mi humilde opinión no tiene mucho sentido. – Marco
Lo que no puedo entender es por qué estás manejando un evento que tu propio repositorio debería publicar. "BookingCreatedEvent" – Marco