大话领域驱动设计——应用层

概述

0762422ec04fb7d439a2ec684225f415.png

应用层是基于领域的应⽤程序用例的实现,应⽤程序⽤例可以看作是⽤户界⾯上的⽤户交互。这一篇,我将详细讲解应用层组件及用法。

总览

7da5329b002773680445c82cd69565ba.png

应用层包含以下组件:

数据传输对象(DTO):数据传输对象是一个简单的对象,不包含任何业务逻辑,用于在应用程序和表示层之间数据传输,当我们使用动态WebApi机制时,DTO会作为HTTP API接口传入传出参数。

应用服务(Application Service):应用服务是一个实现应用程序用例的无状态服务。应用程序服务通常获取并返回DTO。在ABP框架中,我们可以将其配置为动态WebApi。

工作单元(UOW):工作单元是一个应该作为一个事务单元来完成的原子工作。UOW内部的所有操作都应该在成功时提交,或者在失败时回滚。

b431817329d55e6341c4f4f9605a7790.png

在ABP框架下,应用层包含以下两个项目:

Application.Contracts项目包含应用服务接口和这些接口所使用的DTO。

Application项目是实现在Contracts项目中定义的接口的基本应用层。

实现细节

1

数据传输对象

f68aecc90056885384beddae6775e5c1.gif

在ABP框架下所有数据传输对象均需实现 IEntityDto 接口,ABP提供了该接口的默认实现类 EntityDto 。

07b345c8b2a74cc675b8727955460e62.gif

EntityDto有泛型和非泛型两种方式,泛型方式即 EntityDto<TKey> 会默认包含该泛型类型的ID,通常和实体中的ID做对应。如果我们不需要传递ID作为参数,则可以使用无泛型的方式作为DTO基类。

3ba6c1bc7ccc9b4b887fe45e0ef8e609.gif

和实体定义相似,ABP为DTO同样定义了包含审计字段的EntityDto基类, CreationAuditedEntityDto 包含记录对象添加时间和添加人的信息, AuditedEntityDto 包含最后修改时间和修改人, FullAuditedEntityDto 包含增删改的所有记录。

2

应用服务

cb400227c1e639e0801c6edf82c1ec7e.gif

在ABP框架规范中,应用服务接口继承自 IApplicationService ,存放于 Application.Contracts 项目中;其实现类继承自 ApplicationService 存放于 Application 项目中。

b2d4d022a0540f114e2eddd5d522447b.gif

在 ApplicationService 基类中,ABP框架默认添加了一些属性对象用于服务方法中调用,这里介绍几个比较常用的属性用途:

CurrentTenant/CurrentUser:

当前租户/当前用户,在应用服务中可以使用它们获取当前调用者的租户信息和用户信息。

f7ec7e6f3d63db3e27c007cfc2e939fc.png

ObjectMapper:

用于配合AutoMapper实现对象映射。

e69458e709466b9334ab8190613fdcab.png

ServiceProvider:

在使用依赖注入时,除常规的构造方法注入、属性注入等方式外,也可以使用ApplicationService中注入的ServiceProvider对象来获取实例。

1aef1e9163401c6fcb2a7fcd8e290323.png

GuidGenerator:

ABP框架提供了一种有序GUID的生成方案,IGuidGenerator是这种方式的接口声明,而在ApplicationService中,ABP默认注入了GuidGenerator对象用于服务内使用。

883961ec23dd35ac332e1f6ff71a0b49.png

UnitOfWorkManager:

用于工作单元处理,其中Current属性代表当前的工作单元。

dd72a2b03d69fba1a04da715b9f44ebf.png

dd372acd22aecdac1d493d53e2eb92ad.gif

在ABP中,还提供了实现默认增删改查方法的类 CrudAppService ,其接口定义为 ICrudAppService 。如果我们的应用服务需要实现增删改查,可直接继承自此类,其中主要包含以下方法:

CreateAsync:

用于添加数据并返回添加后的结果。使用动态WebApi时,该方法会被封装成POST方式HTTP API接口。当实体使用Guid作为主键时,如果接口调用者传入主键,则使用此主键,否则会使用GuidGenerator生成有序主键,如无特殊需求建议使用后者。

78a2290062329a08d859126789bab83d.png

UpdateAsync:

用于修改数据并返回修改后的结果,其方法包含两个参数:id表示需要修改的数据的ID,input为需要修改的对象。使用动态WebApi时,该方法会被封装成PUT方式HTTP API接口。

eeeb060ff7c3353cde80e298902fb292.png

DeleteAsync:

依据ID删除数据。使用动态WebApi时,该方法会被封装成DELETE方式HTTP API接口。

f4420c1f81e0908aa532e310df01e01d.png

GetAsync:

依据ID获取单条数据。使用动态WebApi时,该方法会被封装成GET方式HTTP API接口。

f4b7016c5e8ccbad8c88d2b728692034.png

GetListAsync:

用于获取数据集合。使用动态WebApi时,该方法会被封装成GET方式HTTP API接口。通常情况,我们可以使用 

PagedAndSortedResultRequestDto

 作为参数类型,可自动实现排序和分页,如果我们不需要排序,也可以使用 

PagedResultRequestDto

 作为参数类型。如果我们希望添加数据过滤条件,可以重写CrudAppService中的 

CreateFilteredQueryAsync

 方法。

b4605cf4d20aac65dd721f629d96324b.png

9a28189bd49ce6d7b4f8602cc2db2e01.gif

ABP中,应用服务默认使用AppService结尾,生成动态WebApi时,会自动去掉此后缀。

3f9107134463d93f441ade10501a6cce.png

注意:ABP生成动态WebAPI是依据应用服务的实现类,而如果使用动态客户端代理,是依据应用服务的接口声明。所以需要保证应用服务接口和实现的参数命名严格一致,否则使用动态客户端代理时无法正确传递参数。

3

工作单元

c5ce0958f07687aabe45e825b66d940c.gif

工作单元是对应用程序中数据库连接和事务范围的抽象和控制。默认情况下,ABP每个应用服务方法都是一个工作单元,除基础的工作单元控制外,我们也可以通过在调用仓储增删改方法时将autoSave参数设置为True来强制提交数据。

a800cf4c5337f9cf4f22a12e9aca5a9d.gif

除此之外,我们可以通过特性 [UnitOfWork] 控制工作单元的启用和停用。

a397e474a90c9b824f65dfa5a7d5ec03.gif

在第2章中,我们提到了UnitOfWorkManager对象,在应用服务中,我们可以通过此对象获取当前工作单元或者创建新的工作单元。

4

对象映射关系

2f89f94791e5110c35463f2e5894efb4.gif

除了DDD中定义的各种组件外,我们在ABP vNext框架下编写应用服务时,还需要创建DTO和实体类之间的映射关系,作为AutoMapper框架对象映射的依据。

0bd6c6a775ae805ad92c13e164ce9e72.gif

此代码位于Application项目中以【项目名+ApplicationAutoMapperProfile】命名的类中,在构造方法中,我们可以直接调用 CreateMap<TSource, TDestination> 方法创建TSource到TDestination类型的映射关系。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值