概述
应用层是基于领域的应⽤程序用例的实现,应⽤程序⽤例可以看作是⽤户界⾯上的⽤户交互。这一篇,我将详细讲解应用层组件及用法。
总览
应用层包含以下组件:
数据传输对象(DTO):数据传输对象是一个简单的对象,不包含任何业务逻辑,用于在应用程序和表示层之间数据传输,当我们使用动态WebApi机制时,DTO会作为HTTP API接口传入传出参数。
应用服务(Application Service):应用服务是一个实现应用程序用例的无状态服务。应用程序服务通常获取并返回DTO。在ABP框架中,我们可以将其配置为动态WebApi。
工作单元(UOW):工作单元是一个应该作为一个事务单元来完成的原子工作。UOW内部的所有操作都应该在成功时提交,或者在失败时回滚。
在ABP框架下,应用层包含以下两个项目:
Application.Contracts项目包含应用服务接口和这些接口所使用的DTO。
Application项目是实现在Contracts项目中定义的接口的基本应用层。
实现细节
1
数据传输对象
在ABP框架下所有数据传输对象均需实现 IEntityDto 接口,ABP提供了该接口的默认实现类 EntityDto 。
EntityDto有泛型和非泛型两种方式,泛型方式即 EntityDto<TKey> 会默认包含该泛型类型的ID,通常和实体中的ID做对应。如果我们不需要传递ID作为参数,则可以使用无泛型的方式作为DTO基类。
和实体定义相似,ABP为DTO同样定义了包含审计字段的EntityDto基类, CreationAuditedEntityDto 包含记录对象添加时间和添加人的信息, AuditedEntityDto 包含最后修改时间和修改人, FullAuditedEntityDto 包含增删改的所有记录。
2
应用服务
在ABP框架规范中,应用服务接口继承自 IApplicationService ,存放于 Application.Contracts 项目中;其实现类继承自 ApplicationService 存放于 Application 项目中。
在 ApplicationService 基类中,ABP框架默认添加了一些属性对象用于服务方法中调用,这里介绍几个比较常用的属性用途:
CurrentTenant/CurrentUser:
当前租户/当前用户,在应用服务中可以使用它们获取当前调用者的租户信息和用户信息。
ObjectMapper:
用于配合AutoMapper实现对象映射。
ServiceProvider:
在使用依赖注入时,除常规的构造方法注入、属性注入等方式外,也可以使用ApplicationService中注入的ServiceProvider对象来获取实例。
GuidGenerator:
ABP框架提供了一种有序GUID的生成方案,IGuidGenerator是这种方式的接口声明,而在ApplicationService中,ABP默认注入了GuidGenerator对象用于服务内使用。
UnitOfWorkManager:
用于工作单元处理,其中Current属性代表当前的工作单元。
在ABP中,还提供了实现默认增删改查方法的类 CrudAppService ,其接口定义为 ICrudAppService 。如果我们的应用服务需要实现增删改查,可直接继承自此类,其中主要包含以下方法:
CreateAsync:
用于添加数据并返回添加后的结果。使用动态WebApi时,该方法会被封装成POST方式HTTP API接口。当实体使用Guid作为主键时,如果接口调用者传入主键,则使用此主键,否则会使用GuidGenerator生成有序主键,如无特殊需求建议使用后者。
UpdateAsync:
用于修改数据并返回修改后的结果,其方法包含两个参数:id表示需要修改的数据的ID,input为需要修改的对象。使用动态WebApi时,该方法会被封装成PUT方式HTTP API接口。
DeleteAsync:
依据ID删除数据。使用动态WebApi时,该方法会被封装成DELETE方式HTTP API接口。
GetAsync:
依据ID获取单条数据。使用动态WebApi时,该方法会被封装成GET方式HTTP API接口。
GetListAsync:
用于获取数据集合。使用动态WebApi时,该方法会被封装成GET方式HTTP API接口。通常情况,我们可以使用
PagedAndSortedResultRequestDto
作为参数类型,可自动实现排序和分页,如果我们不需要排序,也可以使用
PagedResultRequestDto
作为参数类型。如果我们希望添加数据过滤条件,可以重写CrudAppService中的
CreateFilteredQueryAsync
方法。
ABP中,应用服务默认使用AppService结尾,生成动态WebApi时,会自动去掉此后缀。
注意:ABP生成动态WebAPI是依据应用服务的实现类,而如果使用动态客户端代理,是依据应用服务的接口声明。所以需要保证应用服务接口和实现的参数命名严格一致,否则使用动态客户端代理时无法正确传递参数。
3
工作单元
工作单元是对应用程序中数据库连接和事务范围的抽象和控制。默认情况下,ABP每个应用服务方法都是一个工作单元,除基础的工作单元控制外,我们也可以通过在调用仓储增删改方法时将autoSave参数设置为True来强制提交数据。
除此之外,我们可以通过特性 [UnitOfWork] 控制工作单元的启用和停用。
在第2章中,我们提到了UnitOfWorkManager对象,在应用服务中,我们可以通过此对象获取当前工作单元或者创建新的工作单元。
4
对象映射关系
除了DDD中定义的各种组件外,我们在ABP vNext框架下编写应用服务时,还需要创建DTO和实体类之间的映射关系,作为AutoMapper框架对象映射的依据。
此代码位于Application项目中以【项目名+ApplicationAutoMapperProfile】命名的类中,在构造方法中,我们可以直接调用 CreateMap<TSource, TDestination> 方法创建TSource到TDestination类型的映射关系。