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

Wesley13
• 阅读 555

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

领域逻辑与仓储持久化。

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

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

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

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,这两个部分大家可以自己去实现,也可以参考我的微信公众号中的课程。

QQ讨论群:309287205

DDD实战进阶视频请关注微信公众号:DDD实战进阶第一波(六):开发一般业务的大健康行业直销系统(实现产品上下文仓储与应用服务层)

点赞
收藏
评论区
推荐文章
可莉 可莉
3年前
2020,最新Model的设计
很多的app使用MVC设计模式来将“用户交互”与“数据和逻辑”分开,而model其中一个重要作用就是持久化。下文中设计的Model可能不是一个完美的,扩展性强的model范例,但在我需要重构的app中,这样的设计能够满足我的需要。关于ModelModel层包含了app的数据与逻辑,Model层中的类需要关心的是数据的表现,存储,以及操
Stella981 Stella981
3年前
2020,最新Model的设计
很多的app使用MVC设计模式来将“用户交互”与“数据和逻辑”分开,而model其中一个重要作用就是持久化。下文中设计的Model可能不是一个完美的,扩展性强的model范例,但在我需要重构的app中,这样的设计能够满足我的需要。关于ModelModel层包含了app的数据与逻辑,Model层中的类需要关心的是数据的表现,存储,以及操
Wesley13 Wesley13
3年前
DDD实战进阶第一波(十一):开发一般业务的大健康行业直销系统(实现经销商代注册用例与登录令牌分发)
前两篇文章主要实现了经销商代注册的仓储与领域逻辑、经销商登录的仓储与相关逻辑,这篇文章主要讲述经销商代注册的用例与经销商登录的查询功能。一.经销商代注册用例在经销商代注册用例中,我们需要传递经销商的基本注册信息,这个信息是做成了DTO对象。1.经销商注册的DTO对象:publicclassAddDealerDTO
Stella981 Stella981
3年前
Hibernate反射DAO模式
在持久层框架中,如果我们要像简单的JDBC连接数据库那样写一个通用的Dao方法的话,那么把JDBC简单的业务逻辑搬到hibernate持久层框架中,当然是不可能的,这里主要的问题就在于hibernate持久层框架中,因为它不是像JDBC那样简单的增删改查的编写,而是要针对实体类映射配置文件来对照数据库表字段进行操作,而且操作是面向对象的查询,不是简单的sql
Wesley13 Wesley13
3年前
DDD实战5 实现上下文服务
通过服务来协调领域对象,来添加产品用例。1.要实现产品上下文的服务,首先新建一个项目,在Product解决方案文件夹下面新建一个项目,项目的名称为:Product.AppSrv。2.这个项目首先引用Product.Domain项目,因为它操作领域对象,所以还要引用DDD.Repositories(为什么不取名Product.Repository呢,因
智慧物流设备和物联网组件化
与人工智能算法一样,智能物流设备和物联网近年来发展迅速,其在仓储、物流、运输、制造(阿里的灰犀牛)等领域的应用加速了自动化和无人供应链的进程。物联网开启万物互联时代,打通现实世界与数字世界的通道。通过传感器,物联网可以将真实的光电信号转化为数据,这
特处士 特处士
2年前
什么是WMS?
WMS,是仓储管理系统的缩写,中文翻译为仓储管理系统,是供应链系统的重要组成部分。采购、生产、仓储、运输构成了供应链的一个大循环。在生活中,几乎所有的企业都离不开这些系统,无论是传统生产企业还是新型电商。这里只讨论关于WMS(https://www
不是海碗 不是海碗
1年前
二维码识别 OCR 原理及如何应用于物流和仓储管理中
在传统的物流和仓储管理中,人工操作容易出现错误和低效率。然而,随着二维码技术的普及和二维码识别OCR接口的应用,物流和仓储管理实现了更高水平的自动化和智能化。通过扫描和解码二维码,物流和仓储管理系统可以实现货物跟踪、库存管理、智能仓库和安全控制等功能,提高了物流效率和仓储管理的准确性。
DDD架构为什么应该首选六边形架构? | 京东云技术团队
采用依赖倒置原则后的分层架构和六边形架构,实际上都符合整洁架构设计理念。但是六边形架构中使用端口与适配器,让应用程序能够以一致的方式被用户、程序、自动化测试、批处理脚本所驱动,同时能够让应用程序边界更加清晰,从而能更好地防止领域层和应用层逻辑泄露到外层。