Обложка канала

.NET Разработчик

Опытный разработчик не так давно зашёл в .Net и поставил цель получить сертификат Microsoft. Свой ежедневный прогресс он описывает на канале .Net Разработчик. Заметки об изученном материале, советы по повышению производительности и поддержке мотивации, ин

.NET Разработчик

3 года назад
Открыть в
День 1636. #DDD Использование Доменных Событий для Построения Слабосвязанных Систем. Начало В программной инженерии «связанность» означает, насколько разные части программной системы зависят друг от друга. Если они тесно связаны, изменения в одной части могут повлиять на другие. Если слабо, изменения в одной части не вызовут больших проблем в остальной системе. Доменные события — это тактический шаблон DDD, который можно использовать для создания слабосвязанных систем. Событие представляет собой произошедший в домене факт. Другие компоненты в системе могут подписаться на это событие и соответствующим образом его обработать. События домена позволяют явно выражать побочные эффекты и обеспечивают лучшее разделение проблем в домене. Это идеальный способ вызвать побочные эффекты для нескольких агрегатов внутри домена. Вы несёте ответственность за то, чтобы публикация события предметной области была транзакционной (об этом позже). Особенности - Неизменяемость — доменные события являются фактами и должны быть неизменными. - Толстые и Тонкие события — сколько информации вам нужно передавать? - Используйте прошедшее время для именования событий. Доменные события и интеграционные события Семантически это одно и то же: представление чего-то, что произошло в прошлом. Однако намерения у них разные. События домена: - публикуются и используется в пределах одного домена; - отправляются с помощью шины сообщений в памяти; - могут обрабатываться синхронно или асинхронно. Интеграционные события: - потребляются другими подсистемами (микросервисы, ограниченные контексты); - отправляются брокером сообщений через очередь; - обрабатываются только асинхронно. Доменные события можно использовать для создания интеграционных событий, выходящих за пределы домена. Реализация Реализовать доменные события можно через создание абстракции IDomainEvent и реализацию INotification в MediatR. Так вы можете использовать поддержку публикации-подписки в MediatR для публикации уведомления одному или нескольким обработчикам.
using MediatR;
public interface IDomainEvent : INotification
{
}

public class CourseCompleted : IDomainEvent
{
  public Guid CourseId { get; init; }
}

Вызов Только сущности могут вызывать доменные события, поэтому создадим базовый класс Entity, сделав метод RaiseDomainEvent защищённым. Доменные события хранятся во внутренней коллекции, чтобы никто не мог получить к ним доступ. GetDomainEvents предназначен для получения моментального снимка коллекции, ClearDomainEvents — для очистки.
public abstract class Entity : IEntity
{
  private readonly List<IDomainEvent> 
   _events = new();

  public IReadOnlyList<IDomainEvent> 
   GetDomainEvents() => _events.ToList();
  
  public void ClearDomainEvents()
   => _events.Clear();

  protected void RaiseDomainEvent(
   IDomainEvent domainEvent)
   => _events.Add(domainEvent);
}

Теперь сущности могут наследовать от Entity и вызывать доменные события:
public class Course : Entity
{
  public Guid Id { get; private set; }
  public CourseStatus Status { get; private set; }
  public DateTime? Completed { get; private set; }

  public void Complete()
  {
    Status = CourseStatus.Completed;
    Completed = DateTime.UtcNow;

    RaiseDomainEvent(
     new CourseCompleted { 
      CourseId = this.Id 
    });
  }
}

Окончание следует… Источник: https://www.milanjovanovic.tech/blog/using-domain-events-to-build-loosely-coupled-systems