2024-11-06 025_在 ASP.NET Core 中實現 DDD(領域驅動設計)
在 ASP.NET Core 中實現 DDD(領域驅動設計),我們可以通過分層架構來將系統中的各個領域邏輯與基礎設施分離。下面,我會用一個具體的情境來展示如何實現 DDD 原則。
情境範例:訂單管理系統
假設我們正在開發一個簡單的訂單管理系統,主要負責處理訂單的創建、取消、更新等操作。
1. 分層架構概述
DDD 的分層架構可以包括以下幾層:
- 領域層(Domain Layer):這是業務邏輯所在的地方,處理與訂單有關的所有核心邏輯。
- 應用層(Application Layer):負責協調應用程式的執行流程,不包含業務邏輯,只是調用領域層來執行具體邏輯。
- 基礎設施層(Infrastructure Layer):負責資料庫訪問、第三方服務交互等技術細節。
- 使用者介面層(UI Layer):包含控制器和 API 入口,處理請求和回應。
2. 實體(Entity)與值物件(Value Object)
在領域層中,我們定義了訂單(Order)這個實體。訂單包含唯一的訂單 ID,並且具有訂單狀態等屬性。另一個值物件可能是 Money
,表示訂單的金額。
Order
實體範例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
| public class Order { public Guid OrderId { get; private set; } public DateTime CreatedAt { get; private set; } public OrderStatus Status { get; private set; } public Money TotalAmount { get; private set; }
public void Cancel() { if (Status == OrderStatus.Completed) throw new InvalidOperationException("Completed orders cannot be cancelled."); Status = OrderStatus.Cancelled; }
public void Complete() { if (Status == OrderStatus.Cancelled) throw new InvalidOperationException("Cancelled orders cannot be completed."); Status = OrderStatus.Completed; }
public static Order Create(Guid orderId, Money totalAmount) { return new Order { OrderId = orderId, CreatedAt = DateTime.UtcNow, Status = OrderStatus.Pending, TotalAmount = totalAmount }; } }
public enum OrderStatus { Pending, Completed, Cancelled }
public class Money { public decimal Amount { get; } public string Currency { get; }
public Money(decimal amount, string currency) { Amount = amount; Currency = currency; } }
|
在這裡,我們定義了 Order
實體,其中包含訂單的核心屬性和行為,例如取消訂單、完成訂單等。Money
是一個值物件,用來表示訂單的金額,具有金額和貨幣屬性。
3. 應用層(Application Layer)
應用層負責協調流程,它不包含業務邏輯,而是通過調用領域層的實體和服務來處理具體的業務操作。
應用服務範例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| public class OrderService { private readonly IOrderRepository _orderRepository;
public OrderService(IOrderRepository orderRepository) { _orderRepository = orderRepository; }
public async Task<Guid> CreateOrder(decimal amount, string currency) { var order = Order.Create(Guid.NewGuid(), new Money(amount, currency)); await _orderRepository.AddAsync(order); return order.OrderId; }
public async Task CancelOrder(Guid orderId) { var order = await _orderRepository.GetByIdAsync(orderId); order.Cancel(); await _orderRepository.UpdateAsync(order); }
public async Task CompleteOrder(Guid orderId) { var order = await _orderRepository.GetByIdAsync(orderId); order.Complete(); await _orderRepository.UpdateAsync(order); } }
|
這個 OrderService
類別作為應用層的一部分,負責處理訂單的業務流程,但具體的業務邏輯由領域層的 Order
實體來執行。IOrderRepository
是一個存儲庫介面,處理數據存取的具體實現。
4. 基礎設施層(Infrastructure Layer)
基礎設施層負責實現資料庫訪問和其他技術細節,具體實現 IOrderRepository
。
存儲庫實現範例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| public interface IOrderRepository { Task<Order> GetByIdAsync(Guid orderId); Task AddAsync(Order order); Task UpdateAsync(Order order); }
public class OrderRepository : IOrderRepository { private readonly ApplicationDbContext _dbContext;
public OrderRepository(ApplicationDbContext dbContext) { _dbContext = dbContext; }
public async Task<Order> GetByIdAsync(Guid orderId) { return await _dbContext.Orders.FindAsync(orderId); }
public async Task AddAsync(Order order) { await _dbContext.Orders.AddAsync(order); await _dbContext.SaveChangesAsync(); }
public async Task UpdateAsync(Order order) { _dbContext.Orders.Update(order); await _dbContext.SaveChangesAsync(); } }
|
這裡的 OrderRepository
使用 Entity Framework Core
作為數據訪問層,實現了 IOrderRepository
來處理訂單的存取和更新。
5. 使用者介面層(UI Layer)
在這一層,API 控制器負責處理 HTTP 請求,並調用應用層服務來執行操作。
控制器範例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| [ApiController] [Route("api/orders")] public class OrdersController : ControllerBase { private readonly OrderService _orderService;
public OrdersController(OrderService orderService) { _orderService = orderService; }
[HttpPost] public async Task<IActionResult> CreateOrder(decimal amount, string currency) { var orderId = await _orderService.CreateOrder(amount, currency); return Ok(orderId); }
[HttpPost("{orderId}/cancel")] public async Task<IActionResult> CancelOrder(Guid orderId) { await _orderService.CancelOrder(orderId); return NoContent(); }
[HttpPost("{orderId}/complete")] public async Task<IActionResult> CompleteOrder(Guid orderId) { await _orderService.CompleteOrder(orderId); return NoContent(); } }
|
這個 OrdersController
負責接收來自用戶的 HTTP 請求,並且通過 OrderService
來調用領域層中的業務邏輯。
小結
- 領域層:處理核心業務邏輯,確保所有業務規則在這裡實現。
- 應用層:協調業務流程,調用領域層來執行操作,不直接實現業務邏輯。
- 基礎設施層:處理資料庫交互,與外部服務的集成等技術細節。
- 使用者介面層:通過 API 控制器處理用戶請求,調用應用層進行業務操作。
在這個例子中,通過使用 DDD 原則,我們將業務邏輯、數據訪問和應用程式邏輯明確地分離,實現了清晰的責任分層,使得系統更具可維護性和擴展性。
這樣的架構模式有助於處理更複雜的業務需求,你可以依據具體的場景進一步擴展領域模型和服務。