Guid созданного совокупного корня в CQRS
Глядя на этот код отсюда:
[Serializable]
public class CreateClientCommand : Command
{
public string ClientName { get; private set; }
public string Street { get; private set; }
public string StreetNumber { get; private set; }
public string PostalCode { get; private set; }
public string City { get; private set; }
public string PhoneNumber { get; private set; }
public CreateClientCommand(Guid id, string clientName, string street, string streetNumber, string postalCode, string city, string phoneNumber) : base(id)
{
ClientName = clientName;
Street = street;
StreetNumber = streetNumber;
PostalCode = postalCode;
City = city;
PhoneNumber = phoneNumber;
}
}
Guid здесь просто актуален для команды. Это не Guid (потенциально) созданного совокупного корня. Какова лучшая практика для получения этого Guid и как любые возможные ошибки проверки передаются обратно в код, который помещает команду в шину? Например, вот так:
_bus.Publish(new CreateClientCommand(
Guid.NewGuid(),
_clientDetailsReport.ClientName,
_clientDetailsReport.Street,
_clientDetailsReport.StreetNumber,
_clientDetailsReport.PostalCode,
_clientDetailsReport.City,
_clientDetailsView.PhoneNumber));
_bus.Commit();
Я понимаю, что CQRS обычно реализует возможную последовательность. Это означает, что может пройти некоторое время, прежде чем клиент будет создан. Некоторый код MVC/CQRS использует этот подход:
[HttpPost]
public ActionResult Add(DiaryItemDto item)
{
ServiceLocator.CommandBus.Send(new CreateItemCommand(Guid.NewGuid(),item.Title,item.Description,-1,item.From,item.To));
return RedirectToAction("Index");
}
Очевидно, что на индексной странице может отображаться некоторая сетка, содержащая DiaryItems, и пользователь может увидеть последний созданный DiaryItem (потенциальная возможность через некоторое время). Любая обратная связь будет очень ценится. Благодарю.
3 ответа
Вы спрашиваете о разнице между идентификатором самой команды и идентификатором сущности, которую она может создать? Первый тип обычно представляет собой проблему инфраструктуры, обнаруженную в чем-то вроде конверта сообщения, скрытого в протоколе RPC или тому подобном. Последний будет частью вашего домена. (Хотя во многих случаях неплохо рассматривать идентификатор объекта как проблему инфраструктуры, так как вы можете выбрать его для удобства в своей модели постоянства.)
Самый простой способ сделать это - использовать guid, который вы передаете команде, в качестве фактического агрегатного идентификатора, и тогда он у вас есть, и вам не нужно ждать, пока он будет передан обратно на событие
Не уверен, почему у вашей команды есть идентификатор, который смущает вещи (да, некоторые распределенные системы используют это, но это должно быть последним средством). Большинство разработчиков увидят это как идентификатор агрегата.
Обычно просто создайте агрегатный идентификатор и отправьте его с помощью команды. Ведь команда создает сущность..
Команды в большинстве случаев должны быть синхронизированы, чтобы вы могли отбрасывать ошибки обратно. С асинхронными командами вам действительно нужно перезвонить для успеха или неудачи (и асинхронность должна использоваться только там, где у вас действительно есть потребность, это увеличивает стоимость системы).
Вы не переходите к следующему шагу (если вам нужен следующий шаг) до тех пор, пока A) Это система, которая имеет дело с возможной последовательностью, многие бизнес-логики делают это. например, ожидание обмена или третьей стороны для обработки чего-либо, затем работа ожидает этой информации. (Т.е. команда создает Заказ, но обработка заказа, например, OrderDetail, может еще не быть там, и заказ имеет состояние Обработки Заказа) B) У вас есть успешный, тайм-аут или неудачный ответ на команду, прежде чем продолжить.