Должен ли я добавить элемент, используя шаблон репозитория или событие create, если я использую события домена?
Я пытаюсь понять шаблон событий домена, проиллюстрированный Уди Даханом, в отношении добавления новых объектов домена в определенной ситуации.
Теперь обычно с сущностями я бы их создал, а затем добавил через репозиторий. Я предполагаю, что я все еще буду делать это?
Мой пример - мы обычно добавляем активы в систему. Как это:
var asset= new Asset();
/*bunch of prop setting*/
_assetRepository.Add(asset);
Однако создание активов - это событие, в результате которого мы хотим следовать определенным процессам. Поэтому разработчик предложил, что нам больше не нужно делать это, поскольку это может быть обработано событием домена:
var asset= new Asset();
/*bunch of prop setting*/
asset.Create(location);
Теперь метод create вызовет событие и будет обработан обработчиком события create, который в основном просто вставляет его в репозиторий, а некоторые другие вещи отправляют по электронной почте менеджеру хранилища местоположения создания и т. Д.
Однако наличие события create в активе выглядит для меня довольно активной записью. Однако в области люди говорят о создании новых активов. Поэтому мы не были уверены.
Мысли?
2 ответа
Событие созданного домена должно вызываться в конструкторе Asset
класс, потому что это, когда этот конкретный объект создается. В вашей текущей реализации это будет ошибочным, поскольку сущность Asset предоставляет конструктор без параметров. Вместо этого создайте конструктор, который имеет все необходимые свойства в качестве параметров, тем самым предотвращая создание объекта Asset в несогласованном состоянии. Это может выглядеть так:
public class Asset
{
public Asset(string prop1, decimal prop2)
{
this.Prop1 = prop1;
this.Prop2 = prop2;
DomainEvents.Raise(new AssetCreated(prop1, prop2));
}
public string Id { get; private set; }
public string Prop1 { get; private set; }
public decimal Prop2 { get; private set; }
}
Вы все еще должны сохранять сущность, используя репозиторий после его создания. Это может быть проблематично, потому что обработчики для AssetCreated
не может ссылаться на свой идентификатор, так как он еще не назначен, когда они уведомлены. При использовании источника событий событие создания будет явно сохранено в базовом хранилище событий.
Я боролся за эту проблему довольно давно. Но нет хорошего решения. Я думаю,
- Событие домена не должно публиковаться или обрабатываться до успешного сохранения совокупности, к которой оно относится
- На уровне приложений не лежит ответственность публиковать какие-либо события домена
До сих пор я думаю, что лучший подход - это использовать преимущества АОП. Мы можем "запускать" события в агрегате, но вместо того, чтобы отправлять их мгновенно, мы сохраняем их в очереди и действительно отправляем после успешной транзакции.
Мы можем определить пользовательский перехватчик @Transactional для достижения этой цели, таким образом не давая службе приложения знать любое понятие "публикации событий".