Возможны ли события C # для событий домена в DDD? - PullRequest
0 голосов
/ 10 ноября 2019

Я читал, что люди используют библиотеки диспетчеризации событий для доменных событий в своем доменном дизайне.

В языке C # есть встроенная поддержка событий с использованием event ключевое слово вместе с классом EventHandler<>. Можно ли использовать это вместо библиотеки диспетчера событий (например, MediatR )?

Я знаю, что доменные события часто отправляются при сохранении, а не при вызове метода в агрегате,Но, добавив события в List<Action>, вы можете отложить возникновение событий.

Объявление события:

public event EventHandler<InvoiceCreatedEventArgs> InvoiceCreated;

Отложенное поднятие события:

private ICollection<Action> _events = new List<Action>();

public void AddDomainEvent(Action action)
{
    _events.Add(action);
}

protected virtual void OnInvoiceCreated(InvoiceCreatedEventArgs e)
{
    AddDomainEvent(() => { InvoiceCreated?.Invoke(this, e); });
}

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

Не будет ли это немногонежелательная черта для повторной подписки на каждый случай? Будет ли приложение отписываться тоже?

Если события не были объявлены как static, но я слышал плохие вещи о статических событиях и утечках памяти. Будет ли это проблемой?

Если бы использовались события C #, они принадлежали бы к корневому агрегату или принадлежали бы в хранилище?

Если бы события были объявлены в хранилище (что моглобудет Entity Framework Core DbContext), тогда при регистрации обработчиком зависимостей ASP.NET Core с использованием метода .AddDbContext он будет зарегистрирован с временем жизни " Scoped " (один раз на запрос клиента), поэтомуесли события не должны были быть объявлены как статические, тогда приложение должно было бы повторно подписываться на каждый новый экземпляр репозитория, который происходил бы при каждом новом входящем HTTP-запросе.

Использует события C # для событий домена в приложении, использующемВозможен ли дизайн, управляемый предметной областью, или это нежизнеспособная злополучная идея?

1 Ответ

0 голосов
/ 11 ноября 2019

Без проведения различий между событиями в C # и событиями в домене трудно следить за вашим повествованием. Однако, если я правильно понимаю ваше предложение, вы представляете компонент C #, который прослушивает поток событий Entity, а затем публикует эти входящие события домена через события C # для слушателей в приложении. Если это то, что вы предлагаете, то вам придется приложить немало усилий, чтобы заставить его работать, и это не сработает.

Если мы посмотрим на Mediatr, он подписывается на источник событий и создает новые командные процессоры. обрабатывать входящие события домена. Ключ заключается в том, что он создает новые командные процессоры, поэтому он может вызывать метод для них. Кроме того, существует однозначное соответствие между событием домена и командным процессором, и при запуске системы ничего не требуется, кроме самого Mediatr.

С событиями C # командный процессор создается чем-то, затемрегистрируется для получения событий C # определенного типа. Командный процессор инициирует связь, а не подписчик источника события. Чтобы обработать все виды событий, при запуске вы должны будете создать хотя бы один из командных процессоров каждого типа и позволить ему зарегистрироваться в качестве получателя сообщений C #, которые переносят событие домена в качестве полезной нагрузки.

Тогда что происходит, когда вы начинаете масштабирование? Mediatr хорошо масштабируется, поскольку создает командный процессор для каждого события домена. Ваше предложение не будет масштабироваться, потому что для обработки 2 событий одного и того же типа вам нужно будет вручную создать 2 командных процессора, и каждый из этих командных процессоров получит ОБА из входящих событий домена, поскольку они оба подписаны на одно и то же событие C #.

Можно закодировать весь этот беспорядок, но это то, что Джимми Богард уже сделал. Вместо того, чтобы переписывать все, что просто запускает NuGet, отключите Mediatr, а затем играйте со своими детьми в течение всего сэкономленного времени.

...