ABP文檔 - 對象與對象之間的映射

来源:http://www.cnblogs.com/kid1412/archive/2017/05/08/ObjectToObjectMapping.html
-Advertisement-
Play Games

文檔目錄 本節內容: 簡介 IObjectMapper 介面 集成 AutoMapper 安裝 創建映射 自動映射的特性 自定義映射 擴展方法 MapTo 單元測試 預定義的映射 LocalizableString -> string 註入 IMapper 安裝 創建映射 自動映射的特性 自定義映射 ...


文檔目錄

 

本節內容:

 

簡介

把一個對象映射到另一個相似的對象很常見,兩個對象(類)具有相似或相同的屬性,它們之間要互相映射,其實這項工作重覆且無聊,考慮一個典型的應用服務方法,如下:

public class UserAppService : ApplicationService
{
    private readonly IRepository<User> _userRepository;

    public UserAppService(IRepository<User> userRepository)
    {
        _userRepository = userRepository;
    }

    public void CreateUser(CreateUserInput input)
    {
        var user = new User
        {
            Name = input.Name,
            Surname = input.Surname,
            EmailAddress = input.EmailAddress,
            Password = input.Password
        };

        _userRepository.Insert(user);
    }
}

CreateUserInput是一個簡單的數據傳輸對象,User是一個簡單的實體,我們根據傳入的input手工創建一個User實體,現實應用里User實體將會有更多的屬性,手工創建它就會變得很無聊且容易出錯,而且,當我們添加新的屬性到User和CreateUserInput時,又需要修改映射的代碼。

其實我們可以用一個類庫來自動完成映射,AutoMapper是一個最好的對象到對象的映射類庫,Abp中定義了IObjectMapper介面來抽象它,且在 Abp.AutoMapper包中實現了這個介面。

 

IObjectMapper 介面

IObjectMapper是一個簡單的包含把一個對象映射到另一個對象的方法的抽象,我們可以用如下代碼書寫上例:

public class UserAppService : ApplicationService
{
    private readonly IRepository<User> _userRepository;
    private readonly IObjectMapper _objectMapper;

    public UserAppService(IRepository<User> userRepository, IObjectMapper objectMapper)
    {
        _userRepository = userRepository;
        _objectMapper = objectMapper;
    }

    public void CreateUser(CreateUserInput input)
    {
        var user = _objectMapper.Map<User>(input);
        _userRepository.Insert(user);
    }
}

Map是一個簡單的方法,它獲取源對象並且根據泛型參數給定的類型創建一個對應的新的目標對象(此示例中的User),Map有一個重載版本,它把一個對象映射到一個已存在的對象,假設我們已經有一個User實體,想根據另一個對象更新這個實體的屬性:

public void UpdateUser(UpdateUserInput input)
{
    var user = _userRepository.Get(input.Id);
    _objectMapper.Map(input, user);
}

  

集成 AutoMapper

Abp.AutoMapper nuget包(模塊)實現了IObjectMapper介面並且提供了額外功能。

 

安裝

首先,安裝Abp.AutoMapper nuget包到你的項目里:

Install-Package Abp.AutoMapper

然後,在你的模塊上方添加對AbpAutoMapperModule 的依賴:

[DependsOn(typeof(AbpAutoMapperModule))]
public class MyModule : AbpModule
{
    ...
}

接下來,你就可以在你代碼里放心地註入和使用IObjectMapper,當然,你如有需要,也可以使用 AutoMapper自身API。

 

創建映射

AutoMapper要求在映射前,先定義兩個類之間的映射關係,你可以查閱一下它的文檔以瞭解更多詳情,Abp把它變得更簡單和模塊化

 

自動映射的特性

大部分情況下,你只想要直接(並且按約定)映射類,這種情況下,你可以使用AutoMap,AutoMapFrom和AutoMapTo特性。例如,當我們想映射上例中的CreateUserInput到User類,我們可以像如下所示的AutoMapTo特性:

[AutoMapTo(typeof(User))]
public class CreateUserInput
{
    public string Name { get; set; }

    public string Surname { get; set; }

    public string EmailAddress { get; set; }

    public string Password { get; set; }
}

AutoMap特性在兩個類之間雙向映射,但在這個示例里,我們只需要從CreateUserInput映射到User,所以我們只需要用AutoMapTo.

 

自定義映射

簡單地映射可能不適用於一些場景,如,兩個類的屬性名稱有些不同或你可能想要在映射過程中忽略一些屬性,這些情況下可以直接使用AutoMapper的Api來自定義映射關係,不過Abp.AutoMapper包定義了更模塊化的Api.

假設我們想要忽略Password並把用EmailAddress映射到User的Email,我們可以作如下的定義:

[DependsOn(typeof(AbpAutoMapperModule))]
public class MyModule : AbpModule
{
    public override void PreInitialize()
    {
        Configuration.Modules.AbpAutoMapper().Configurators.Add(config =>
        {
            config.CreateMap<CreateUserInput, User>()
                  .ForMember(u => u.Password, options => options.Ignore())
                  .ForMember(u => u.Email, options => options.MapFrom(input => input.EmailAddress));
        });
    }
}

AutoMapper有更多的選項和功能來映射對象,你可以查看它的文檔瞭解更多。

 

擴展方法 MapTo

建議註入和使用前面說的IObjectMapper介面,因為它使我們的項目儘可能地與AutoMapper解藕,並且使單元測試更加容易,因為我們可以在單元測試里替換(模擬)映射。

Abp.AutoMapper模塊里同樣定義了MapTo這個擴展方法,它可以在不註入IObjectMapper的情況下把一個對象映射到另一個對象,例如:

public class UserAppService : ApplicationService
{
    private readonly IRepository<User> _userRepository;

    public UserAppService(IRepository<User> userRepository)
    {
        _userRepository = userRepository;
    }

    public void CreateUser(CreateUserInput input)
    {
        var user = input.MapTo<User>();
        _userRepository.Insert(user);
    }

    public void UpdateUser(UpdateUserInput input)
    {
        var user = _userRepository.Get(input.Id);
        input.MapTo(user);
    }
}

MapTo擴展方法定義在 Abp.AutoMapper 命名空間里,所以你需要先在你的代碼里引入命名空間。

由於MapTo擴展方法是靜態的,它們使用AutoMapper的靜態實例(Mapper.Instance),這樣對於應用代碼來說,比較簡單和好用,但是在單元測試里由於靜態配置和映射是在不同的測試之間共用它,它們相互影響 ,可能會帶來一些問題。

 

單元測試

我們想把每個單元測試獨立開來,所以我們需要為我們的項目定義如下規則:

1.只使用IObjectMapper,不使用擴展方法MapTo.

2.配置Abp.AutoMapper 模塊,使用局部的Mapper實例(用單例的方式註冊到依賴註入)不用靜態的(Abp.AutoMapper預設情況下,使用靜態的Mapper.Instance,從而可以像上面那樣使用MapTo擴展方法):

Configuration.Modules.AbpAutoMapper().UseStaticMapper = false;

  

預定義的映射

LocalizableString -> string

Abp.AutoMapper模塊定義了一個從LocalizableString (或 ILocalizableString) 對象到string對象的映射,它使用ILoclaizationManager進行轉換,所以在映射過程中,可以本地化的屬性會自動的本地化。

 

註入 IMapper

如果你需要註入AutoMapper的IMapper對象來代替IObjectMapper,就直接在你的類里註入IMapper並使用它,Abp.AutoMapper包把IMapper作為單例註冊到了依賴註入系統里。

 


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

-Advertisement-
Play Games
更多相關文章
  • shell的性質 Linux系統的shell相當於操作系統的“一層外殼”,它是命令語言解釋器,它為用戶提供了使用操作系統的介面。它不屬於內核,而是在內核之外以用戶態方式運行。它的基本功能是解釋並執行用戶打入的各種命令,實現用戶與Linux內核的介面。 個人理解:shell就是普通的用戶態程式,能夠理 ...
  • 前言:學習通配符有點為正則表達式打基礎的感覺……之前學python有學過正則表達式,所以這篇博客學起來還是挺快的。 特殊符號 通配符 他是shell的內置功能通配符,用過DOS的應該很瞭解,也很常用。通配符,指包含這些字元的字元串“?”,“*”,“[]”,{} 通配符含義 >匹配文件名 通配符詳解 ...
  • 不同的軟體的安裝方法是並不相同的。有的軟體只能通過特定的方法來安裝。 在不同的Linux發行版本上安裝同一個軟體的方法也未必相同, 因此有的時候,你在網上找到的在Ubuntu上安裝某個軟體的方法,也許在CentOS上並不能成功。 RPM、YUM、dpkg、apt-get、aptitude ...
  • Linux GSO邏輯分析 ——lvyilong316 (註:kernel版本linux 2.6.32) GSO用來擴展之前的TSO,目前已經併入upstream內核。TSO只能支持tcp協議,而GSO可以支持tcpv4, tcpv6, udp等協議。在GSO之前,skb_shinfo(skb)有兩 ...
  • 文件屬性概述(ls -lhi) linux里一切皆文件Linux系統中的文件或目錄的屬性主要包括:索引節點(inode),文件類型,許可權屬性,鏈接數,所歸屬的用戶和用戶組,最近修改時間等內容: 解釋: 第一列:inode索引節點編號(相當於人的身份證,全國唯一)第二列:文件類型及許可權第二列共11個字 ...
  • Download opencv https://github.com/opencv/opencv/tree/2.4 安裝必要的依賴 Enter opencv dirctory and install cmake 出錯,報錯如下 根據報錯信息,應該是qt沒裝 安裝qt cmake成功會生成如下文件 t ...
  • 廣義的網站的監控涵蓋所有的非業務行為的數據採集與管理,包括數據分析師和產品設計師使用的網站用戶行為日誌、業務運行數據,以及供運維工程師和開發工程師使用的性能統計數據等。 本文主要是通過shell腳本來收集伺服器性能指標,如系統load、記憶體占用、磁碟IO、CPU占用,並將其寫入一個文件中,及時判斷應 ...
  • 最近做了一個使用 C# 寫了一個發送郵件的 windows 服務,在這裡記錄一下。 首先使用 Visual Studio 2015 創建一個 windows 服務項目。 然後在設計器上面右擊添加安裝程式。如下圖。 安裝好後,選擇安裝程式設計界面,選擇服務和安裝程式右擊選擇屬性修改一些屬性值。 PS: ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...