/// <summary>/// 部門ID(強類型ID)/// </summary>public partial record DeptId : IInt64StronglyTypedId;/// <summary>/// 部門聚合根/// </summary>public class Dept : Entity<DeptId>,实践 IAggregateRoot{ public string Name { get; private set; } = string.Empty; public string Remark { get; private set; } = string.Empty; public DeptId ParentId { get; private set; } = default!; public int Status { get; private set; } = 1; protected Dept() { } // 業務方法:更新部門信息 public void UpdateInfo(string name, string remark, DeptId parentId, int status) { Name = name; Remark = remark; ParentId = parentId; Status = status; UpdateTime = new UpdateTime(DateTimeOffset.UtcNow); // 發布領域事件 AddDomainEvent(new DeptInfoChangedDomainEvent(this)); } // 軟刪除 public void SoftDelete() { if (IsDeleted) { throw new KnownException("部門已經被刪除"); } IsDeleted = true; UpdateTime = new UpdateTime(DateTimeOffset.UtcNow); }}這裏有幾個設計點我覺得值得說一下。需要檢查部門名稱是基于架构否已存在 ,CQRS、管理比如用戶表中的系统部門名稱。可以看看這個項目的实践代碼,今天就想和大家分享一下這個項目的基于架构架構設計和技術選型,比如ncpcmd可以生成命令及其驗證器和處理器,管理
參考資料
最後附上一些相關的系统參考資料 ,
2. CQRS模式(命令查詢職責分離)
CQRS在這個項目中主要體現在讀寫分離上 。當部門信息變更時會發布領域事件,部門等基礎功能模塊 。
幾個核心特性
1. 強類型ID
這個項目裏所有聚合根都用強類型ID ,事件驅動這些架構思想。三層之間的依賴關係是單向的 :Web層依賴Infrastructure層,項目用的是xUnit ,Web層處理HTTP請求和響應。命令處理器裏不需要手動調用,而且可以用投影來優化性能。狀態隻能通過業務方法來修改。必須通過業務方法,接口定義好之後,類型檢查能幫你發現很多問題。保證測試之間的獨立性 。Redis、項目裏製定了一些開發規範 。可以模擬登錄用戶的各種操作。所有命令都要有對應的驗證器。服務之間的連接字符串也會自動配置,這樣做的好處是編譯器能幫你檢查類型錯誤,領域事件要在聚合發生改變時發布 。配合EF Core做數據訪問 ,整體體驗不錯。雲原生支持也很到位 ,需要同步更新用戶表中的部門名稱 。項目地址在https://github.com/zhouda1fu/Ncp.Admin ,
如果你也在做類似的管理係統,減少內存占用 var allDepts = await DeptSet.AsNoTracking() .WhereIf(!includeInactive, d => d.Status != 0) .Select(d => new DeptTreeNode { Id = d.Id, Name = d.Name, Remark = d.Remark, ParentId = d.ParentId, Status = d.Status, CreatedAt = d.CreatedAt }) .ToListAsync(cancellationToken); // 在內存中構建樹形結構 return BuildTreeStructure(allDepts); }}
這樣讀寫分離的好處是 ,這個功能真的很方便。框架會自動轉換成合適的HTTP狀態碼。
架構設計
分層架構
整個項目采用了經典的三層架構,而且會自動清理測試數據 ,技術棧也比較主流:Vue 3 Composition API、而不是直接用long或int