Именно так я обычно и делаю, используя Mediatr.
Возвращает класс-обертку.
Если мы возьмем пример CancelOrder
примера eShopOnContainers, у меня будет команда, возвращающая CancelOrderCommandResult
public class CancelOrderCommand : IRequest<CancelOrderCommandResult>
{ }
CancelOrderCommandResult
может быть чем-то вроде этого:
public class CancelOrderCommandResult
{
public CancelOrderCommandResult(IEnumerable<Error> errors)
{
Success = false;
Errors = errors;
}
public CancelOrderCommandResult(bool success)
{
Success = success;
}
public bool Success {get; set;}
public IEnumerable<Error> Errors {get; set;}
}
Я пропустил класс Error
, но это мог быть просто POCO, содержащий информацию об ошибке,код ошибки и т. д. *
Затем наш обработчик становится
public class CancelOrderCommandHandler : IRequestHandler<CancelOrderCommand, CancelOrderCommandResult>
{
private readonly IOrderRepository _orderRepository;
public CancelOrderCommandHandler(IOrderRepository orderRepository)
{
_orderRepository = orderRepository;
}
public async Task<bool> Handle(CancelOrderCommand command, CancellationToken cancellationToken)
{
var orderToUpdate = await _orderRepository.GetAsync(command.OrderNumber);
if(orderToUpdate == null)
{
return false;
}
try
{
orderToUpdate.SetCancelledStatus();
await _orderRepository.UnitOfWork.SaveEntitiesAsync();
//iff success, return true
return new CancelOrderCommandResult(true);
}
catch (Exception ex)
{
var errors = MapErrorsFromException(ex);
return new CancelOrderCommandResult(errors)
}
}
}
Опять же, MapErrorsFromException
опущен для краткости, но вы можете даже вставить это как зависимость.
В вашем контроллере, когда вы звоните _mediator.Send
, вы теперь получаете CancelOrderCommandResult
- и если .Success
- true, возвращайте 200, как и раньше.
В противном случае у вас есть набор ошибок - скоторые вы можете принять решение о том, что вернуть - 400, 500 и т. д ...