I want to save an order with order items with prices in my write database. But firstly I need to fetch products with their prices because I don't trust a user - he could pass a lower price, that's why I don't want to add a Price property to CreateOrderDTO.
Where should I fetch product prices? In a command handler - if yes then from which database: read database or write database? Or maybe in a controller before sending a command?
The flow in my application is the following:
API - the controller:
[HttpPost] public async Task<IActionResult> CreateOrder(CreateOrderDTO orderDto) { var orderCmd = new CreateOrderCommand(orderDto.CustomerId, orderDto.OrderItems); await _mediator.Send(orderCmd); } The CreateOrderDTO model:
public class CreateOrderDTO { public Guid CustomerId { get; set; } public List<CreateOrderItemDTO> OrderItems { get; set; } } public class CreateOrderItemDTO { public Guid ProductId { get; set; } public int Quantity { get; set; } } The command and command handler:
public class CreateOrderCommand : IRequest { public Guid CustomerId { get; } public List<CreateOrderItemDTO> OrderItems { get; } public CreateOrderCommand(Guid customerId, List<CreateOrderItemDTO> orderItems) { CustomerId = customerId; OrderItems = orderItems; } } public class CreateOrderCommandHandler : IRequestHandler<CreateOrderCommand> { private readonly IEventStoreRepository _eventStoreRepository; public CreateCustomerCommandHandler( IEventStoreRepository eventStoreRepository) { _eventStoreRepository = eventStoreRepository; } public async Task<Unit> Handle(CreateOrderCommand request, CancellationToken cancellationToken) { var order = new Order(Guid.NewGuid(), request.CustomerId); foreach (var item in request.OrderItems) { order.AddOrderItem(item.ProductId, item.Quantity, /* I need a price here */); } await _eventStoreRepository.Save(order); return Unit.Value; } } And my aggregate root:
public class Order : AggregateRoot { public Guid Id { get; private set; } public Guid CustomerId { get; private set; } public List<OrderItem> OrderItems { get; private set; } public Order(Guid id, Guid customerId) { OrderItems = new List<OrderItem>(); } public void AddOrderItem(Guid productId, int quantity, decimal price) { //... } }