Предоставление пользователям немедленного ответа в Event Driven Architecture
Я много читал об Event Driven Architecture, и для меня это имеет большой смысл, но проблема предоставления пользователям немедленной обратной связи сбивает меня с толку.
Скажем, есть служба (EmployeeService), которая содержит список всех сотрудников. Бизнес-логика для создания сотрудника находится в этом сервисе.
Пользовательский интерфейс из другой системы использует этот сервис. Требуется (нравится вам это или нет), что у него есть сетка сотрудников и "кнопка добавления сотрудника", которая вызывает форму, и когда вы отправляете форму, она возвращает вас в группу с новым сотрудником в Это. Сетка показывает производные поля, которые рассчитываются службой (это важно отметить!).
Традиционно при отправке я бы отображал экран загрузки, синхронно отправлял запрос WCF о регистрации сотрудника и, когда это было выполнено, перенаправлялся в сетку (в которой определенно теперь будет новый сотрудник).
При EDA при отправке я бы "запустил и забыл" команду для регистрации пользователя - но что тогда? Я мог бы переслать в сеть, но есть шанс, что нового сотрудника там еще не может быть? Я мог бы вручную добавить к сетке, предполагая, что все будет в порядке, но как я могу отобразить производные данные, рассчитанные службой? Или, может быть, я мог бы отобразить "график ожидания нового сотрудника" в сетке, если он еще не создан, а затем заставлять страницу проверять каждые несколько секунд, пока она не появится?
Это общий сценарий, так каково общее решение для этого?
2 ответа
Вы можете зарегистрировать обратный вызов при отправке команды и заблокировать, пока команда не будет завершена.
Если вы скачали пакет NServiceBus, просто обратитесь к примеру решения AsyncPagesMvc3. Это пример того, что вы ищете.
Если твой EmployeeService
является службой SOA, тогда кнопка "Добавить сотрудника" также принадлежит службе EmployeeService. Пользовательский интерфейс представляет собой простой набор из нескольких сервисов. Вы можете развернуть часть EmployeeService
локально на клиенте, который обрабатывает создание сотрудника и расчет (если расчет не является сложным).
Например:
public class AddEmployeeView
{
public IBus Bus { get; set; }
public void AddNewClicked() {
// async calculate
// store directly in the employee service database
// or dispatch command internally
// refresh employee list as the service is the only owner of that data
Bus.Publish<NewEmployeeAdded>(m => { });
}
}
Так что выше AddEmployeeView
принадлежит к EmployeeService
, EmployeeService
один знает, как рассчитывать и хранить новых сотрудников (даже в собственной базе данных), и является единственным логическим издателем NewEmployeeAdded
событие. И тут уходит твоя сложность.