Как мне обновить агрегат дочернего в DDD? - PullRequest
0 голосов
/ 25 января 2019

Я пробую архитектуру в стиле DDD с ядром asp.net, но у меня возникают проблемы с пониманием того, как обновить дочерние объекты совокупного корня после его создания.

У меня есть класс заказа, который имееттолько для чтения список OrderLines.Эти строки заказа могут быть обновлены или удалены из заказа.Заказ всегда будет редактироваться во внешнем интерфейсе за одну транзакцию (публикация в API).

Я создал методы для этого в совокупности заказов, но кажется, что логика не в том месте.Является ли это правильным способом обновления / удаления дочерних объектов в DDD?

Поскольку Заказ поступит в API в режиме PUT, я проверяю, не являются ли какие-либо элементы, находящиеся на объекте из БД,во входящих данных.Если нет, я удаляю их.Если они есть, я обновляю их.

Это относится к классу обслуживания?Какова лучшая практика в DDD?

public class Order : BaseEntity, IAggregateRoot
    {
        public Order(List<OrderItem> items, Address shippingAddress, int customerId)
        {
            ShipToAddress = shippingAddress ?? throw new Exception("Can not be null");
            _orderItems = items ?? throw new Exception("Can not be null");
            CustomerId = customerId;
            Status = OrderStatus.Processing;
        }

        private readonly List<OrderItem> _orderItems = new List<OrderItem>();

        public IReadOnlyCollection<OrderItem> OrderItems => _orderItems.AsReadOnly();

        public void AddOrUpdateOrderItem(ProductOrdered itemOrdered, decimal unitPrice, int units, DateTime deliverDate, int orderItemId)
        {
            var existingOrderLine = _orderItems.Where(o => o.Id == orderItemId)
                .SingleOrDefault();

            if (existingOrderLine != null)
            {
                existingOrderLine.Update(itemOrdered, unitPrice, units, deliverDate);
            }
            else
            {
                //add validated new order item
                var orderItem = new OrderItem(itemOrdered, unitPrice, units, deliverDate);
                _orderItems.Add(orderItem);
            }
        }
        public void RemoveOrderLines(List<int> orderItemIds)
        {   
            foreach (var item in _orderItems.ToList())
            {
                var containsItem = orderItemIds.Any(newOrderLine => newOrderLine == item.Id);
                if (!containsItem)
                {
                    _orderItems.Remove(item);
                }
            }
        }
    }

OrderLine:

public class OrderItem : BaseEntity
    {
        public ProductOrdered ItemOrdered { get; private set; }
        public decimal UnitPrice { get; private set; }
        public int Units { get; private set; }
        public DateTime DeliveryDate { get; set; }
        public OrderLineStatus OrderLineStatus { get; set; }

        private OrderItem()
        {
            // required by EF
        }

        public OrderItem(ProductOrdered itemOrdered, decimal unitPrice, int units, DateTime deliverDate)
        {
            ItemOrdered = itemOrdered;
            UnitPrice = unitPrice;
            Units = units;
            DeliveryDate = deliverDate;
            OrderLineStatus = OrderLineStatus.Waiting;
        }

        public void Update(ProductOrdered itemOrdered, decimal unitPrice, int units, DateTime deliverDate)
        {
            ItemOrdered = itemOrdered;
            UnitPrice = unitPrice;
            Units = units;
            DeliveryDate = deliverDate;
        }
    }

1 Ответ

0 голосов
/ 31 января 2019

Я создал методы для этого в совокупности заказов, но кажется, что логика не в том месте. Это правильный способ обновления / удаления дочерних объектов в DDD? Да. Мне просто не нравится, что 2 отдельных варианта использования определены в одном. Я бы сделал Добавить в seaparate метод и Обновить в другой. Относительно положить конечную точку. Рассмотрите возможность использования основанного на задачах пользовательского интерфейса. Он подходит к DDD намного лучше, чем операция по положению CrudBased. Поэтому определите команды - AddLineItemCommand, UpdateLineItemCommand, RemoveLineItemCommand и различные операции POST для них. Относитесь к каждому варианту использования по-разному.

...