abp(net core)+easyui+efcore实现仓储管理系统——ABP整体介绍(一)html
abp(net core)+easyui+efcore实现仓储管理系统——解决方案介绍(二)数据库
abp(net core)+easyui+efcore实现仓储管理系统——领域层建立实体(三)app
abp(net core)+easyui+efcore实现仓储管理系统——定义仓储并实现 (四)async
在上一篇文章中学习了ABP的仓储(Repository)功能,Repository对数据库进行增删改查操做。在这一篇文章中咱们主要了解应用服务层。post
1、解释下应用服务层学习
应用服务用于将领域(业务)逻辑暴露给展示层。展示层经过传入DTO(数据传输对象)参数来调用应用服务,而应用服务经过领域对象来执行相应的业务逻辑而且将DTO返回给展示层。所以,展示层和领域层将被彻底隔离开来。
如下几点,在建立应用服务时须要注意:ui
2、定义应用服务接口须要用到的DTOspa
1. 在Visual Studio 2017的“解决方案资源管理器”中,右键单击“ABP.TPLMS.Application”项目。 选择“添加” > “新建文件夹”。3d
2.将文件夹命名为“Modules”。日志
3. 右键单击“Modules”文件夹,选择“添加” > “新建文件夹”。将文件夹重命名为“Dto”。以下图。
4. 右键单击“Dto”文件夹,而后选择“添加” > “类”。 将类命名为 ModuleDto,而后选择“添加”。代码以下。
using Abp.Application.Services.Dto; using Abp.AutoMapper; using ABP.TPLMS.Entitys; using System; using System.Collections.Generic; using System.Text; namespace ABP.TPLMS.Modules.Dto { [AutoMapFrom(typeof(Module))] public class ModuleDto:EntityDto<long> { public string DisplayName { get; set; } public string Name { get; set; } public string Url { get; set; } public string HotKey { get; set; } public int ParentId { get; set; } public bool RequiresAuthentication { get; set; } public bool IsAutoExpand { get; set; } public string IconName { get; set; } public int Status { get; set; } public string ParentName { get; set; } public string RequiredPermissionName { get; set; } public int SortNo { get; set; } } }
Dto
被用来将模块数据传递到基础设施层。Dto
继承自 EntityDto<long>
.跟在领域层定义的Module类同样具备一些相同属性。[AutoMapFrom(typeof(Module))]
用来建立从Module类到ModuleDto
的映射.使用这种方法。你能够将Module对象自动转换成ModuleDto
对象(而不是手动复制全部的属性)。5. 右键单击“Dto”文件夹,而后选择“添加” > “类”。 将类命名为 CreateUpdateModuleDto ,而后选择“添加”。代码以下。
using Abp.Application.Services.Dto; using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Text; namespace ABP.TPLMS.Modules.Dto { public class CreateUpdateModuleDto : EntityDto<long> { public const int MaxLength = 255; [Required] [StringLength(MaxLength)] public string DisplayName { get; set; } [Required] [StringLength(MaxLength)] public string Name { get; set; } [Required] [StringLength(MaxLength)] public string Url { get; set; } [StringLength(MaxLength)] public string HotKey { get; set; } public int ParentId { get; set; } public bool RequiresAuthentication { get; set; } public bool IsAutoExpand { get; set; } [StringLength(MaxLength)] public string IconName { get; set; } public int Status { get; set; } [Required] [StringLength(MaxLength)] public string ParentName { get; set; } [StringLength(MaxLength)] public string RequiredPermissionName { get; set; } public int SortNo { get; set; } } }
6. 为何须要经过dto进行数据传输?
通常来讲,使用DTO进行数据传输具备如下好处。
7.Dto规范 (灵活应用)
定义完DTO,是否是脑壳有个疑问,我在用DTO在展示层与应用服务层进行数据传输,但最终这些DTO都须要转换为实体才能与数据库直接打交道啊。若是每一个dto都要本身手动去转换成对应实体,这个工做量也是不可小觑啊。
聪明如你,你确定会想确定有什么方法来减小这个工做量。
3、使用AutoMapper自动映射DTO与实体
1.简要介绍AutoMapper
开始以前,若是对AutoMapper不是很了解,建议看下这篇文章AutoMapper小结。
AutoMapper的使用步骤,简单总结下:
在Abp中有两种方式建立映射规则:
2.为Module实体相关的Dto定义映射规则
ModuleDto、CreateUpdateModuleDto中的属性名与Module实体的属性命名一致,且只须要从Dto映射到实体,不须要反向映射。因此经过AutoMapTo建立单向映射便可。
[AutoMapTo(typeof(Module))] //定义单向映射 public class ModuleDto:EntityDto<long> { ... } [AutoMapTo(typeof(Module))] //定义单向映射 public class CreateUpdateModuleDto : EntityDto<long> { ... }
4、定义IModuleAppService接口
1. 右键单击“Dto”文件夹,而后选择“添加” > “新建项”,在弹出对话框中选择“接口”。为应用服务定义一个名为 IModuleAppService
的接口。代码以下。
using Abp.Application.Services; using Abp.Application.Services.Dto; using ABP.TPLMS.Modules.Dto; using System; using System.Collections.Generic; using System.Text; using System.Threading.Tasks; namespace ABP.TPLMS.Modules { public interface IModuleAppService : IApplicationService { Task CreateAsync(CreateUpdateModuleDto input); Task UpdateAsync(CreateUpdateModuleDto input); Task<ListResultDto<ModuleDto>> GetAllAsync(); Task DeleteAsync(int Id); void Delete(int Id); } }
从上面的代码中咱们仔细看一下方法的参数及返回值,你们可能会发现并未直接使用Module实体对象。这是为何呢?由于展示层与应用服务层是经过Data Transfer Object(DTO)进行数据传输。
5、实现IModuleAppService
对于具体的业务来说,只是简单的增删该查,实现起来就很简单了。代码以下:
using Abp.Application.Services; using Abp.Application.Services.Dto; using Abp.Domain.Repositories; using ABP.TPLMS.Entitys; using ABP.TPLMS.Modules.Dto; using AutoMapper; using System; using System.Collections.Generic; using System.Text; using System.Threading.Tasks; namespace ABP.TPLMS.Modules { public class ModuleAppService : ApplicationService, IModuleAppService { private readonly IRepository<Module> _moduleRepository; public ModuleAppService(IRepository<Module> moduleRepository) { _moduleRepository = moduleRepository; } public Task CreateAsync(CreateUpdateModuleDto input) { var module = Mapper.Map<Module>(input); return _moduleRepository.InsertAsync(module); } public Task UpdateAsync(CreateUpdateModuleDto input) { var module = Mapper.Map<Module>(input); return _moduleRepository.UpdateAsync(module); } public async Task<ListResultDto<ModuleDto>> GetAllAsync() { var books = await _moduleRepository.GetAllListAsync(); return new ListResultDto<ModuleDto>(ObjectMapper.Map<List<ModuleDto>>(books)); } public async Task DeleteAsync(int Id) { await _moduleRepository.DeleteAsync(Id); } public void Delete(int Id) { _moduleRepository.Delete(Id); } } }