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); } } }