abp(net core)+easyui+efcore倉儲系統——創建應用服務(五)

来源:https://www.cnblogs.com/chillsrc/archive/2019/06/21/11065667.html
-Advertisement-
Play Games

在上一篇文章中學習了ABP的倉儲(Repository)功能,Repository對資料庫進行增刪改查操作。在這一篇文章中我們主要瞭解應用服務層。 應用服務用於將領域(業務)邏輯暴露給展現層。展現層通過傳入DTO(數據傳輸對象)參數來調用應用服務,而應用服務通過領域對象來執行相應的業務邏輯並且將DT... ...


abp(net core)+easyui+efcore倉儲系統目錄

abp(net core)+easyui+efcore倉儲系統——ABP總體介紹(一)

abp(net core)+easyui+efcore倉儲系統——解決方案介紹(二)

abp(net core)+easyui+efcore倉儲系統——領域層創建實體(三)

 abp(net core)+easyui+efcore倉儲系統——定義倉儲並實現 (四)

 

      在上一篇文章中學習了ABP的倉儲(Repository)功能,Repository對資料庫進行增刪改查操作。在這一篇文章中我們主要瞭解應用服務層。

一、解釋下應用服務層

     應用服務用於將領域(業務)邏輯暴露給展現層。展現層通過傳入DTO(數據傳輸對象)參數來調用應用服務,而應用服務通過領域對象來執行相應的業務邏輯並且將DTO返回給展現層。因此,展現層和領域層將被完全隔離開來。
以下幾點,在創建應用服務時需要註意:

  1. 在ABP中,一個應用服務需要實現IApplicationService介面,最好的實踐是針對每個應用服務都創建相應繼承自IApplicationService的介面。(通過繼承該介面,ABP會自動幫助依賴註入)
  2. ABP為IApplicationService提供了預設的實現ApplicationService,該基類提供了方便的日誌記錄和本地化功能。實現應用服務的時候繼承自ApplicationService並實現定義的介面即可。
  3. ABP中,一個應用服務方法預設是一個工作單元(Unit of Work)。ABP針對UOW模式自動進行資料庫的連接及事務管理,且會自動保存數據修改。

二、定義應用服務介面需要用到的DTO

    1. 在Visual Studio 2017的“解決方案資源管理器”中,右鍵單擊“ABP.TPLMS.Application”項目。 選擇“添加” > “新建文件夾”。

    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; }   
    }
}
  • 為了在頁面上展示模塊信息,ModuleDto被用來將模塊數據傳遞到基礎設施層。
  • ModuleDto繼承自 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; }    
    }
}
  • 這個DTO類在創建和更新模塊信息的時候被使用,用來從頁面獲取模塊信息。
  • 類中的屬性定義了數據註解(如[Required])用來定義有效性驗證。ABP會自動校驗DTO的數據有效性。

  6. 為什麼需要通過dto進行數據傳輸?

     一般來說,使用DTO進行數據傳輸具有以下好處。

  • 數據隱藏
  • 序列化和延遲載入問題
  • ABP對DTO提供了約定類以支持驗證
  • 參數或返回值改變,通過Dto方便擴展
  • DTO類被用來在 基礎設施層 和 應用層 傳遞數據.

  7.Dto規範 (靈活應用)

  • ABP建議命名輸入/輸出參數為:MethodNameInput和MethodNameOutput
  • 併為每個應用服務方法定義單獨的輸入和輸出DTO(如果為每個方法的輸入輸出都定義一個dto,那將有一個龐大的dto類需要定義維護。一般通過定義一個公用的dto進行共用)
  • 即使你的方法只接受/返回一個參數,也最好是創建一個DTO類
  • 一般會在對應實體的應用服務文件夾下新建Dtos文件夾來管理Dto類。

      定義完DTO,是不是腦袋有個疑問,我在用DTO在展現層與應用服務層進行數據傳輸,但最終這些DTO都需要轉換為實體才能與資料庫直接打交道啊。如果每個dto都要自己手動去轉換成對應實體,這個工作量也是不可小覷啊。
聰明如你,你肯定會想肯定有什麼方法來減少這個工作量。

三、使用AutoMapper自動映射DTO與實體

    1.簡要介紹AutoMapper

    開始之前,如果對AutoMapper不是很瞭解,建議看下這篇文章AutoMapper小結

     AutoMapper的使用步驟,簡單總結下:

  • 創建映射規則(Mapper.CreateMap<source, destination>();)
  • 類型映射轉換(Mapper.Map<source,destination>(sourceModel))

     在Abp中有兩種方式創建映射規則:

  • 特性數據註解方式:
    • AutoMapFrom、AutoMapTo 特性創建單向映射
    • AutoMap 特性創建雙向映射
  • 代碼創建映射規則:
    • Mapper.CreateMap<source, destination>();

     2.為Module實體相關的Dto定義映射規則

      ModuleDto、CreateUpdateModuleDto中的屬性名與Module實體的屬性命名一致,且只需要從Dto映射到實體,不需要反向映射。所以通過AutoMapTo創建單向映射即可。

  [AutoMapTo(typeof(Module))] //定義單向映射
    public class ModuleDto:EntityDto<long>
{

      ...

}

     [AutoMapTo(typeof(Module))] //定義單向映射
    public  class CreateUpdateModuleDto : EntityDto<long>
    {

      ...

    }

 

四、定義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)進行數據傳輸。

五、實現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);

        }

    }

}

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 迴圈結構 :do-while 迴圈四要素: 1.初始化條件 2.迴圈條件 3.迴圈體 4.迭代條件 格式: 1.初始化條件 do{ 3.迴圈體 4.迭代條件 }while(2.迴圈條件); do-while和while的區別? ...
  • ``` Date: 表示特定的瞬間,精確到毫秒,通過方法設定自己所表示的時間,可以表示任意的時間 System.currentTimeMillis() :返回的當前系統時間, 1970-1-1 至今的毫秒數 SimpleDateFormat sdf = new SimpleDateFormat("y... ...
  • 1.遍歷key值 同理,可把下列代碼的d改為d.keys() notice:python2除了上述兩種方法外,還可以寫為d.iterkeys() 2.遍歷value值 同理,可把下列代碼的d改為d.values() notice:python2除了上述兩種方法外,還可以寫為d.itervalues( ...
  • 容器可設置佈局管理器,管理容器中組件的佈局: container.setLayout(new XxxLayout()); Java有6種佈局管理器,AWT提供了5種: FlowLayout BorderLayout GridLayout GridBagLayout CradLayout Swing還 ...
  • Github https://github.com/gongluck/SDL2 study/tree/master/Csdl2 Csdl2.h Csdl2.cpp 測試 C++ include "Csdl2.h" include include include define TESTCHECKRET ...
  • 讓我們考慮一個簡單的編程挑戰:對大數組中的所有元素求和。現在可以通過使用並行性來輕鬆優化這一點,特別是對於具有數千或數百萬個元素的巨大陣列,還有理由認為,並行處理時間應該與常規時間除以CPU核心數一樣多。事實證明,這一壯舉並不容易實現。我將向您展示幾種並行執行此操作的方法,它們如何改善或降低性能以及 ...
  • 在前面兩篇隨筆《ABP開發框架前後端開發系列---(7)系統審計日誌和登錄日誌的管理》和《ABP開發框架前後端開發系列---(8)ABP框架之Winform界面的開發過程》開始介紹了許可權管理的內容,其中只是列出了內部的許可權系統的審計和登陸信息,以及對Winform界面的整合,本篇隨筆繼續介紹ABP開... ...
  • 軟體開發中最常用的模式之一是緩存,這是一個簡單但非常有效的概念,想法是重用操作結果,執行繁重的操作時,我們會將結果保存在緩存容器中,下次我們需要該結果時,我們將從緩存容器中取出它,而不是再次執行繁重的操作。 例如,要獲得某人的頭像,您可能需要前往資料庫。我們不會每次都執行那次查詢,而是將結果保存在緩 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...