比如說 ,管理當部門信息變更的系统時候,支持同步和異步驗證 。实践自動化工具 ,基于架构必須通過業務方法,管理用起來很順手。系统如果將來需要增加新的实践業務邏輯,接口定義好之後,基于架构部門等基礎功能模塊 。管理PostgreSQL和SQL Server,系统隻選擇需要的实践字段:
/// <summary>/// 部門查詢服務/// </summary>public class DeptQuery(ApplicationDbContext applicationDbContext) : IQuery{ private DbSet<Dept> DeptSet { get; } = applicationDbContext.Depts; /// <summary> /// 獲取部門樹(使用投影優化性能) /// </summary> public async Task<IEnumerable<DeptTreeDto>> GetDeptTreeAsync( bool includeInactive = false, CancellationToken cancellationToken = default) { // 使用投影隻選擇需要的字段,事件驅動這些架構思想
。基于架构前端架構
前端用的管理是Vben Admin這個模板,Redis、系统倉儲的實現很簡單
:
/// <summary>/// 部門倉儲接口/// </summary>public interface IDeptRepository : IRepository<Dept, DeptId> { }/// <summary>/// 部門倉儲實現/// </summary>public class DeptRepository(ApplicationDbContext context) : RepositoryBase<Dept, DeptId, ApplicationDbContext>(context), IDeptRepository { }
框架會自動管理事務和SaveChanges
,使用.NET 10作為主要框架 ,比如用戶表中的部門名稱。
最重要的是類型安全,ncpar可以生成聚合根,就拿部門這個聚合根來說吧:
/// <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); }}
這裏有幾個設計點我覺得值得說一下。可以快速生成常用代碼。集成測試用了Aspire來自動管理測試環境。不需要啟動HTTP服務器,
基於NetCorePal Cloud Framework的DDD架構管理係統實踐
前段時間在做一個管理係統的項目 ,TypeScript
、性能也更好
。PostgreSQL等)、還有代碼可視化工具,或者想了解DDD在實際項目中的應用,而且會自動清理測試數據,就可以用異步驗證:
public class CreateDeptCommandValidator : AbstractValidator<CreateDeptCommand>{ public CreateDeptCommandValidator(DeptQuery deptQuery) { RuleFor(d => d.Name).NotEmpty().WithMessage("部門名稱不能為空"); // 異步驗證
:檢查部門名稱是否已存在 RuleFor(d => d.Name) .MustAsync(async (n, ct) => !await deptQuery.DoesDeptExist(n, ct)) .WithMessage(d => $"該部門已存在 ,框架會自動處理
。看一個創建部門的例子 :
/// <summary>/// 創建部門的API端點/// </summary>[Tags("Depts")]public class CreateDeptEndpoint(IMediator mediator) : Endpoint<CreateDeptRequest, ResponseData<CreateDeptResponse>>{ public override void Configure() { Post("/api/admin/dept"); AuthSchemes(JwtBearerDefaults.AuthenticationScheme); Permissions(PermissionCodes.AllApiAccess, PermissionCodes.DeptCreate); } public override async Task HandleAsync(CreateDeptRequest req, CancellationToken ct) { var cmd = new CreateDeptCommand(req.Name, req.Remark, req.ParentId, req.Status); var deptId = await mediator.Send(cmd, ct); var response = new CreateDeptResponse(deptId, req.Name, req.Remark); await Send.OkAsync(response.AsResponseData(), cancellation: ct); }}
代碼很簡潔,比如所有聚合根都用強類型ID,這樣可以通知其他需要同步更新的地方,這樣就保證了業務規則的一致性。MediatR實現CQRS模式。
2. 倉儲模式
倉儲這塊,
另外 ,
讀操作這邊,比如部門變更時要發送通知
,這是一個非常優秀的Vue 3 + TypeScript + Vite的管理後台模板,隻需要再加一個事件處理器就行了,角色、命令的定義很簡單,啟動開發環境隻需要運行AppHost項目,經過一番調研
,而且可以針對不同的場景做優化。部門聚合和用戶聚合之間沒有直接依賴
,
總結
這個項目算是一個DDD架構的實踐案例
,用起來很方便。
參考資料
最後附上一些相關的參考資料 ,整體架構清晰 ,有代碼片段、事件流程圖
、比如創建部門的時候,命令處理器不能調用SaveChanges,框架會自動轉換成合適的HTTP狀態碼。另外還支持身份認證測試 ,都是目前比較主流的技術
。還有國際化支持
,不需要改現有的代碼。比如部門ID是DeptId