Qualora una radice aggregata evento-sourced avere accesso al repository di eventi di sourcing?

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

Domanda

Sto lavorando su un evento-sourced implementazione CQRS, utilizzando DDD nell'applicazione / strato di dominio. Ho un modello a oggetti che assomiglia a questo:

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 la mia comprensione delle DDD finora, sia persona e prenotazioni sono separate radici di aggregazione per due motivi:

  1. Ci sono momenti in cui componenti aziendali tirerà Booking oggetti separatamente dal database. (Vale a dire, una persona che è stata rilasciata ha una prenotazione precedente modificato a causa di informazioni non corrette).
  2. Non ci dovrebbe essere contesa tra persona e Prenotazioni ogni volta che una prenotazione deve essere aggiornato di blocco.

Un altro requisito business è che una prenotazione non può mai verificarsi per una persona più di una volta in un momento. A causa di questo, sono preoccupato per l'interrogazione del database di query sul lato di lettura come ci potrebbe potenzialmente essere qualche incongruenza lì (a causa dell'uso CQRS e avere un database di lettura alla fine coerente).

Qualora le radici di aggregazione poter interrogare la memoria di supporto evento di origine da id per oggetti (lazy-loading secondo necessità)? Ci sono altre vie di implementazione che avrebbe più senso?

È stato utile?

Soluzione

Prima di tutto, non si ha realmente realmente bisogno di sourcing evento in voi caso

? Sembra abbastanza semplice per me. Evento di sourcing ha sia vantaggi che svantaggi. Mentre ti dà una pista di controllo gratuito e rende il vostro modello di dominio più espressiva, si complica la soluzione.

OK, suppongo che a questo punto si pensava sopra la vostra decisione e si sono decisi a rimanere con il sourcing evento. Penso che ti manca il concetto di messaging come mezzo di comunicazione tra gli aggregati. È descritto meglio in Pat Helland carta (che è, a proposito, non circa DDD o evento Sourcing, ma di scalabilità).

L'idea è aggregati possono inviare messaggi l'un l'altro per costringere alcuni comportamenti. Non ci può essere interazione sincrona (a.k.a metodo call) tra aggregati perché questo introdurrebbe problemi di coerenza.

Nel tuo esempio, una persona AR avrebbe mandato un messaggio Reserve ad una prenotazione AR. Questo messaggio potrebbe essere trasportato in qualche modo asincrono e affidabile. Prenotazioni AR avrebbe gestito questo messaggio e se è già prenotate da un'altra persona, che avrebbe risposto con il messaggio ReservationRejected. In caso contrario, avrebbe mandato ReservationConfirmed. Questi messaggi dovrebbero essere gestite da persona AR. Probabilmente, avrebbero generare ancora un altro evento che si sarebbe trasformato in e-mail inviata al cliente o qualcosa del genere.

Non c'è bisogno di andare a prendere i dati di query nel modello. Proprio messaggistica. Se volete un esempio, è possibile scaricare i sorgenti del ramo "Messaggi" di Ncqrs progetto e dare un'occhiata in classe ScenarioTest. Dimostra di messaggistica tra RA utilizzando campione del carico e degli HandlingEvent dal Blue Book.

La vostra domanda a questo risposta?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top