@WhiteNinja

Что и как должен возвращать Commandhandler при использовании принципа CQRS/CQS?

Добрый день!

Вопрос про использование Command-query separation:

Подскажите пожалуйста как лучше организовать возвращение результата выполнения команды из обработчика (Не какие-то данные, т.е. это не Query, а именно результат выполнения команды) ?

Если рассмотреть пример (ASP.NET MVC):

Есть ProductController в котором есть Action Create - добавление нового продукта. И после создания нового продукта нужно сделать Redirect на страницу с деталями только-что добавленного продукта.

public class ProductController : Controller
{

	private readonly ICommandDispatcher _commandDispatcher;
	
	public ProductController(ICommandDispatcher commandDispatcher)
	{
		_commandDispatcher = commandDispatcher;
	}

	[HttpGet]
	public Action Create()
	{
		// ...
		View(createProductCommand);
	}
	
	[HttpPost]
	public Action Create(CreateProductCommand createProductCommand)
	{	
		if(ModelState.IsValid)
		{
			// Как правильно получить ProductId?
			_commandDispatcher.Dispatch(createProductCommand);			
			return RedirectToAction(nameof(Details), new { id = /* ... тут нужно передать ProductId ...*/ });
		}
		
		return View(createProductVm);
	}
}


Пример обработчика команды:

public CreateProductHandler : ICommandHandler<CreateProductCommand>
{
	private readonly IUnitOfWorkFactory _uowFactory;
	private readonly IProductRepository _productRepository;
	
	public CreateProductHandler(IUnitOfWorkFactory uowFactory, IProductRepository productRepository) 
	{
		_uowFactory = uowFactory;
		_productRepository = productRepository;
	}
	
	// Возвращает void, а нам нужно когда int, когда string. Т.е. в общем случае TCommandResult
	public void Handle(CreateProductCommand command)
	{
		Product product =  new Product(/* ... create from command ... */);
	
		using(var uow = _uowFactory.Create())
		{
			_productRepository.Insert(product);
			uow.Commit();
		}
	}
}


Получается CommandHandler на самом деле должен возвращать какой-то TCommandResult, а не void?

Другой пример это при удалении нескольких продуктов нужно вернуть число удаленных в результате команды продуктов, чтобы вывести на экран сообщения $"Удалено {x} продуктов".

При этом всем Грег Янг говорит, что обработчик команды как раз может возвращать список ошибок или исключение. (25 минута).
  • Вопрос задан
  • 154 просмотра
Пригласить эксперта
Ответы на вопрос 1
@ggrnd0
CommandHandler должен вернуть состояние операции.
В частности, если вместо исполнения команды, она ставится в очередь, надо вернуть токен.

По итогу имеем (к черту всех этих Янги и прочих) разделять разделить Command и Query невозможно - контракты идентичны.
Но это только в случае если ты собираешься CQRS имплементировать в реальном приложении, а не для написания очередной бестолковой статьи о сферическом коне в вакууме...
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы