Полученный событием совокупный корень должен иметь доступ к репозиторию определения источника события?

Я работаю над полученной событием реализацией 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 до сих пор, и Человек и Заказ являются отдельным агрегатом, поддерживает две причины:

  1. Существуют времена, когда бизнес-компоненты вытянут объекты Заказа отдельно от базы данных. (т.е., у человека, который был выпущен, есть предыдущий заказ, измененный из-за неправильной информации).
  2. Там не должен блокировать конкуренцию между Человеком и Заказывать каждый раз, когда Заказ должен быть обновлен.

Еще одно бизнес-требование состоит в том, что Заказ никогда не может происходить для Человека несколько раз за один раз. Из-за этого, я обеспокоен запросами базы данных запроса по стороне чтения, поскольку могло потенциально быть некоторое несоответствие там (из-за использования CQRS и наличия в конечном счете последовательной базы данных чтения).

Совокупным корням нужно позволить запросить полученное событием запоминающее устройство идентификатором для объектов (ленивая загрузка их по мере необходимости)? Есть ли какие-либо другие пути реализации, которая имела бы больше смысла?

5
задан JD Courtoy 26 May 2010 в 20:35
поделиться

1 ответ

Прежде всего, действительно ли вам нужен источник событий в вашем случае? Мне это кажется довольно простым. Поиск событий имеет как преимущества, так и недостатки. Хотя это дает вам бесплатный контрольный журнал и делает модель вашей предметной области более выразительной, это усложняет решение.

Хорошо, я предполагаю, что на этом этапе вы обдумали свое решение и полны решимости придерживаться источников событий. Я думаю, что вам не хватает концепции обмена сообщениями как средства связи между агрегатами.Лучше всего он описан в статье Пэта Хелланда (которая, кстати, касается не DDD или поиска событий, а масштабируемости).

Идея состоит в том, что агрегаты могут отправлять друг другу сообщения, чтобы вызвать какое-то поведение. Между агрегатами не может быть синхронного (также известного как вызов метода) взаимодействия, потому что это приведет к проблемам с согласованностью.

В вашем примере человек AR отправит сообщение о резервировании в Booking AR. Это сообщение будет передаваться асинхронным и надежным способом. Booking AR обработает это сообщение и, если оно уже забронировано другим человеком, ответит сообщением ReservationRejected. В противном случае он отправит ReservationConfirmed. Эти сообщения должны обрабатываться персоналом AR. Возможно, они сгенерируют еще одно событие, которое будет преобразовано в электронное письмо, отправленное заказчику, или что-то в этом роде.

Нет необходимости получать данные запроса в модели. Просто обмен сообщениями. Если вам нужен пример, вы можете скачать исходники ветки «Сообщения» проекта Ncqrs и взглянуть на класс ScenarioTest. Он демонстрирует обмен сообщениями между AR с использованием примера Cargo и HandlingEvent из Синей книги.

Это ответ на ваш вопрос?

11
ответ дан 13 December 2019 в 19:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: