從這篇文章開始,咱們根據前面的DDD理論與DDD框架的約束,正式進入直銷系統案例的開發。數據庫
本篇文章主要講產品上下文中的領域層的主要實現,先簡單講下業務方面的需求:產品SPU與產品SKU,產品SPU主要是產品的名字和相關描述,微信
產品SKU包括產品SPU的多個規格,每一個規格有不一樣的價格與PV值。從咱們對DDD概念的理解,產品SPU與產品SKU屬於同一個聚合,產品SPU是聚合根。框架
產品上下文主要實現產品的上架功能,爲了實現上架功能,咱們首先要實現產品上下文的領域POCO模型與領域邏輯,ide
咱們將產品的POCO模型與領域邏輯創建到一個叫Product.Domain的項目中。工具
產品SPU領域對象POCO代碼:ui
public partial class ProductSPU : IAggregationRoot { [Key] public Guid Id { get; set; } public string Code { get; set; } public string ProductSPUName { get; set; } public string ProductSPUDes { get; set; } public List<ProductSKU> ProductSKUS { get; set; } }
產品SKU領域對象POCO代碼:this
public partial class ProductSKU : IEntity { public ProductSKU() { } [Key] public Guid Id { get; set; } public string Code { get; set; } public string Spec { get; set; } public Unit Unit { get; set; } public decimal PV { get; set; } public decimal DealerPrice { get; set; } public byte[] Image { get; set; } public Guid ProductSPUId { get; set; } public string ProductSPUName { get; set; } }
從上面代碼能夠看到,ProductSPU從聚合根接口繼承,ProductSKU從實體接口繼承,ProductSPU包含了一個ProductSKU的集合(也就是引用),這就表明它們同屬一個聚合,在具體使用EF Core作spa
持久化時,會做爲一個事務統一持久化。code
領域對象除了包含自身的屬性,也應該包括自身的業務邏輯,產品上架的功能比較簡單,業務邏輯也比較簡單,主要就是如何生成整個領域對象,以及聚合根與實體業務標識符Code的生成規則。視頻
產品SPU領域對象業務邏輯代碼:
public partial class ProductSPU { public ProductSPU CreateProductSPU(Guid id,string spuname,string spudesc,List<ProductSKU> productskus) { this.Id = id; this.Code = "Code " + spuname; this.ProductSPUName = spuname; this.ProductSKUS = productskus; this.ProductSPUDes = spudesc; return this; } }
產品SKU領域對象業務邏輯代碼:
public partial class ProductSKU { public ProductSKU CreateProductSKU(string productspuname,Guid productspuid, byte[] image,decimal dealerprice,decimal pv,string unit,string spec) { this.Id = Guid.NewGuid(); this.ProductSPUId = productspuid; this.Code = "Code " + productspuname + spec; this.ProductSPUName = productspuname; this.Image = image; this.DealerPrice = dealerprice; this.PV = pv; switch (unit) { case "盒": this.Unit = Unit.盒; break; case "包": this.Unit = Unit.包; break; case "瓶": this.Unit = Unit.瓶; break; } this.Spec = spec; return this; } }
我將領域對象的屬性與領域對象的邏輯分到不一樣的cs文件中,便於不一樣職責人開發與管理,並且採用相同的名稱空間和Partial關鍵字。
Product.Domain除了要實現領域邏輯以外,還要定義ProductSPU的倉儲接口、經過EF Core定義產品上下文與數據庫上下文之間的映射關係。
倉儲接口定義:
public interface IProductRepository { void CreateProduct<T>(T productspu) where T : class, IAggregationRoot; }
從上面能夠看到,這個接口其實就是定義了將ProductSPU這個聚合根持久化到數據庫與的接口。
產品上下文與數據庫上下文映射關係:
1.由於映射關係使用EF Core實現,將來可能被替換掉,因此先定義一個產品上下文接口:
public interface IProductContext { }
2.EF Core映射實現
public class ProductEFCoreContext:DbContext,IProductContext { public DbSet<ProductSPU> ProductSPU { get; set; } public DbSet<ProductSKU> ProductSKU { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder optionBuilder) { optionBuilder.UseSqlServer("數據庫鏈接字符串"); } }
3.使用EF Core工具生成數據庫腳本並更新數據庫,在生成腳本時,須要編輯項目文件,並採用EF Core Tools命令生成,這裏就不細講EF Core技術方面的內容。
到這裏,咱們就基本實現了產品上下文的領域層,能夠看到領域層主要是領域邏輯,定義了一個倉儲接口,將數據庫技術解耦,固然要定義領域對象與數據庫之間的映射關係,不然用例沒法完成真正
對領域對象的持久化。
QQ討論羣:309287205
DDD實戰進階視頻請關注微信公衆號: