dotnet-cqrs/docs/tutorials/modular-solution/02-domain-layer.md

2.2 KiB

Domain Layer

Define domain entities, value objects, and events.

Create Order Entity

// OrderManagement.Domain/Entities/Order.cs
namespace OrderManagement.Domain.Entities;

public class Order
{
    public int Id { get; private set; }
    public int CustomerId { get; private set; }
    public OrderStatus Status { get; private set; }
    public decimal TotalAmount { get; private set; }
    public DateTimeOffset PlacedAt { get; private set; }

    private readonly List<OrderItem> _items = new();
    public IReadOnlyList<OrderItem> Items => _items.AsReadOnly();

    private Order() { } // EF Core

    public static Order Create(int customerId, List<OrderItem> items)
    {
        if (!items.Any())
            throw new InvalidOperationException("Order must have at least one item");

        var order = new Order
        {
            CustomerId = customerId,
            Status = OrderStatus.Placed,
            PlacedAt = DateTimeOffset.UtcNow
        };

        order._items.AddRange(items);
        order.TotalAmount = items.Sum(i => i.Price * i.Quantity);

        return order;
    }

    public void Ship()
    {
        if (Status != OrderStatus.Placed)
            throw new InvalidOperationException($"Cannot ship order in {Status} status");

        Status = OrderStatus.Shipped;
    }

    public void Cancel()
    {
        if (Status == OrderStatus.Shipped)
            throw new InvalidOperationException("Cannot cancel shipped order");

        Status = OrderStatus.Cancelled;
    }
}

public class OrderItem
{
    public int ProductId { get; set; }
    public string ProductName { get; set; } = string.Empty;
    public int Quantity { get; set; }
    public decimal Price { get; set; }
}

public enum OrderStatus
{
    Placed,
    Shipped,
    Cancelled
}

Domain Events

// OrderManagement.Domain/Events/OrderPlacedEvent.cs
namespace OrderManagement.Domain.Events;

public record OrderPlacedEvent
{
    public int OrderId { get; init; }
    public int CustomerId { get; init; }
    public decimal TotalAmount { get; init; }
    public DateTimeOffset PlacedAt { get; init; }
    public List<OrderItem> Items { get; init; } = new();
}

Next Steps

Continue to CQRS Layer