DDD实战进阶第一波(六):开发一般业务的大健康行业直销系统(实现产品上下文仓储与应用服务层)

前一篇文章我们完成了产品上下文的领域层,我们已经有了关于产品方面的简单领域逻辑,我们接着来实现产品上下文关于仓储持久化与应用层的用例如何来协调

领域逻辑与仓储持久化。

首先大家需要明确的是,产品上下文的领域逻辑是系统的核心,它不应该依赖仓储,而仓储应该要依赖领域层,这样仓储才可以把领域逻辑执行完后,才可能将

领域对象持久化到数据库中,这一点与传统的架构有本质的区别。

一般我们会在解决方案中建立一个项目,这个项目就是包含了所有聚合的仓储实现,具体不同上下文的仓储实现,可以在这个项目下建立不同的文件夹。

1.产品上下文仓储实现:

 public class ProductEFCoreRepository : IProductRepository
    {
        private readonly DbContext context;
        public ProductEFCoreRepository(DbContext context)
        {
            this.context = context;
        }
        public void CreateProduct<T>(T productspu) where T:class,IAggregationRoot
        {
            var productdbcontext = this.context as ProductEFCoreContext;
            var productspunew = productspu as ProductSPU;
            try
            {
                productdbcontext.ProductSPU.Add(productspunew);
            }
            catch(Exception error)
            {
                throw error;
            }
        }
      
    }

上面的代码有几个要注意的方面:

a.首先会从产品的仓储接口做继承,通过EF Core的机制,实现了仓储接口的CreateProduct方法。

b.使用了产品上下文的EF Core数据访问上下文ProductEFCoreContext完成了Productspu的数据库预添加。

c.上一个说法中,可能大家有两个疑惑,一是为什么不使用productdbcontext标记ProductSPU为Added状态,而是使用.Add方法,二是为什么只是完成了添加状态,

而不再后续调用Commit或SaveChange方法真正持久化到数据库中?首先,因为未来持久化要将这个聚合中的ProductSPU聚合根与ProductSKU实体作为一个整体持久化到数据库中,

而Added状态只能将当前聚合根作为添加状态,而不能同时将引用的ProductSKU对象作为添加状态,所以不能使用Added状态而使用.Add方法;其次仓储实现聚合提交时,只进行数

据库预添,是因为协调领域逻辑与仓储的应用服务层用例可能涉及到多个聚合,所以可能要同时调用多个领域对象的业务逻辑,多个仓储,完成后,将多

聚合作为一个整体事务做提交,所以真正的提交应该放到应用服务层更合适,而不是仓储层。

2.产品上架应用服务层实现:

应用服务层实际就是完成用例,通过应用服务层调用领域逻辑,然后通过应用服务层调用仓储,最后应用服务层做真正的提交,这样就把职责分的非常清楚,也在领域逻辑不依赖

仓储的前提下,完成了整个用例和持久化。

a.首先我们在产品上下文的应用服务层项目中,建立需要添加的产品SPU与对应产品SKU的DTO对象

 public class AddProductSPUDTO
    {
        public string SPUName { get; set; }
        public string SPUDesc { get; set; }
        public List<string> SKUSpecs { get; set; }
        public List<string> SKUUnits { get; set; }
        public List<decimal> SKUDealerPrices { get; set; }
        public List<byte[]> SKUImages { get; set; }
        public List<decimal> SKUPvs { get; set; }
    }

b.建立一个上架产品的用例服务,协调领域逻辑与仓储完成用例

public class AddProductSPUUseCase:BaseAppSrv
    {
        private readonly IRepository irepositorycontext;
        private readonly IProductRepository iproductrepository;
        public AddProductSPUUseCase(IRepository irepositorycontext,IProductRepository iproductrepository)
        {
            this.irepositorycontext = irepositorycontext;
            this.iproductrepository = iproductrepository;
        }

        public ResultEntity<bool> AddProduct(AddProductSPUDTO addproductspudto)
        {
            var productspuid = Guid.NewGuid();
            var productskus = new List<ProductSKU>();
            for(int i = 0; i < addproductspudto.SKUSpecs.Count; i++)
            {
                var productsku = new ProductSKU().CreateProductSKU(addproductspudto.SPUName,
                    productspuid, addproductspudto.SKUImages[i], addproductspudto.SKUDealerPrices[i],
                    addproductspudto.SKUPvs[i], addproductspudto.SKUUnits[i], addproductspudto.SKUSpecs[i]);
                productskus.Add(productsku);
            }
            var productspu = new ProductSPU().CreateProductSPU(productspuid, addproductspudto.SPUName,
                addproductspudto.SPUDesc, productskus);
            try
            {
                using (irepositorycontext)
                {
                    iproductrepository.CreateProduct(productspu);
                    irepositorycontext.Commit();
                }
                return GetResultEntity(true);
            }
            catch(Exception error)
            {
                throw error;
            }
        }
    }

BaseAppSrv是你要定义的一个类,它的GetResultEntity方法功能是完成用例后后,返回接口层的数据格式,这个数据格式会进一步通过接口层返回给前端,返回

的数据格式就是ResultEntity<T>,这两个部分大家可以自己去实现,也可以参考我的微信公众号中的课程。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏腾讯大讲堂的专栏

【扩展阅读】流氓软件你造吗?

“流氓软件”是介于病毒和正规软件之间的软件,通俗地讲是指在使用电脑上网时,不断跳出的窗口让自己的鼠标无所适从;有时电脑浏览器被莫名修改增加了许多工作条,当用户打...

2188
来自专栏Java学习123

基于python的终端天气查询

3666
来自专栏SAP最佳业务实践

SAP最佳业务实践:SD–售前活动(920)-2询价、报价

一、 VA11询价 客户询问某一产品的价格。将由销售代表使用建议的价格在系统中创建询价。此价格必须通过负责经理审批。之后该价格将成为已批准状态,并且可以将其作为...

3865
来自专栏FreeBuf

深度剖析幽灵电子书 | 一双窥视安全人员的无形之眼

0x01 事件经过 2016年2月26日,一个网络安全相关的QQ群内,一名用户分享了一份名为“网络安全宝典.chm”的电子书供大家下载,瑞星网络安全工程师Bfi...

1947
来自专栏阮一峰的网络日志

一些新闻媒体的全文Feed

订阅Feed的时候,最烦恼的是有些Feed只输出摘要,必须点击到原始网页上才能看到全文。如果原始网页被屏蔽了,那就更麻烦了。

2194
来自专栏云计算D1net

如何使用PaaS作为安全控制的试验平台

美国商务部国家标准与技术研究所(NIST)在2014年12月发布了特别出版物800-53A修订版4,概述了高级信息系统安全官(ISSO)和信息系统所有者(ISO...

3336
来自专栏跨界架构师

分布式系统中的必备良药 —— 全局唯一单据号生成

  我们作为一个软件系统,肯定到处充满着各种单据,也必然需要有各种单据号与之对应。比如:电商行业的订单号、支付流水号、退款单号等等。SCM的采购单号、进货单号、...

1592
来自专栏FreeBuf

利用蓝牙从FUZE获取信用卡数据测试

这篇文章主要讨论关于FUZE Card智能卡的安全问题,这是一种带有蓝牙功能的可编程信用卡,它的大小跟普通信用卡一样,但FUZE可以取代至少30张信用卡,也就是...

1313
来自专栏流星博客

有毒的二维码和链接?请不要误导大家好吗?

今天在知乎上看到的一篇文章,本想分享给某群的群友们看的,结果刚分享就有人说广告?!我说不是,结果他说链接有毒?!!

2696
来自专栏hadoop学习

Hadoop新手篇:hadoop入门基础教程

关于hadoop的分享此前一直都是零零散散的想到什么就写什么,整体写的比较乱吧。最近可能还算好的吧,毕竟花了两周的时间详细的写完的了hadoop从规划到环境安装...

1094

扫码关注云+社区

领取腾讯云代金券