В моем приложении ASP.NET MVC3/NHibernate есть требование отключить и обработать различные события, связанные с объектами моего домена. Например, объект Order
может иметь такие события, как OrderStatusChanged
или NoteCreatedForOrder
. В большинстве случаев эти события приводят к отправке электронного письма, поэтому я не могу просто оставить их в приложении MVC.
Я прочитал Udi Dahan События домена и десятки других мыслей о том, как это сделать, и я решил используя узел NServiceBus, который обрабатывает сообщения о событиях. Я сделал несколько пробных доказательств, и это, похоже, хорошо работает.
Мой вопрос , какой уровень приложения должен действительно поднимать события. Я не хочу запускать события до тех пор, пока объект, о котором идет речь, не будет успешно сохранен (не может отправить электронное письмо, которое было создано записью, если сбой сохранения не удалось).
Еще одна проблема заключается в том, что в некоторых случаях событие привязывается к объекту, который находится под совокупным корнем. В приведенном выше примере a Note
сохраняется путем добавления его в коллекцию Order.Notes
и сохранения порядка. Это создает проблему в том, что сложно оценить, какие события следует запускать при сохранении Order
. Я хотел бы избежать необходимости вытаскивать текущую копию объекта и искать различия до сохранения обновленной копии.
-
Соответствует ли пользовательскому интерфейсу повышение этих событий? Он знает, какие события произошли, и может их запустить только после успешного сохранения уровня обслуживания. Что-то просто кажется неправильным в том, что контроллер отключает события домена.
-
Должен ли репозиторий отключать события после успешного сохранения?
-
Следует ли вообще отделять события, хранить хранилище объекта
Event
, который затем подбирается службой poller, а затем превращается в событие для NServiceBus (или обрабатывается непосредственно из службы poller)? -
Есть ли лучший способ сделать это? Может быть, мои объекты домена останавливают события, которые запускаются на уровне сервиса только после того, как объект сохраняется?
-
Обновление: У меня есть сервисный уровень, но для него сложнее и сложнее проследить процесс сопоставления, чтобы определить, какие события должны быть запущены при сохранении заданного корня. Поскольку некоторые из этих событий являются деталями (например, "статус заказа изменен" ), я думаю, что мне нужно будет восстановить копию объекта DB, сравнить свойства для создания событий, сохранить новый объект, а затем отправить события в NServiceBus, когда операция сохранения успешно завершена.
Update
То, что я закончил, после ответа, который я опубликовал ниже (ниже), должен был встроить в мои объекты домена свойство EventQueue
, которое было List<IDomainEvent>
. Затем я добавил события, поскольку изменения в домене заслужили его, что позволило мне сохранить логику внутри домена, что, по моему мнению, уместно, поскольку я запускаю события на основе того, что происходит внутри объекта.
Затем, когда я сохраняю объект на своем уровне обслуживания, я обрабатываю эту очередь и фактически отправляю события на служебную шину. Вначале я планировал использовать устаревшую базу данных, в которой использовались идентификационные ПК, поэтому мне пришлось после этого обработать эти события, чтобы заполнить идентификатор объекта, но в конечном итоге я решил переключиться на Guid.Comb
PK, что позволяет мне пропустить этот шаг.