Mapster 高階功能解析:高效物件對映與最佳化技巧

努力,努力再努力發表於2024-11-05

在現代開發中,物件之間的轉換是常見且繁瑣的任務,尤其是在多層架構或跨系統資料傳輸的場景下。Mapster 是一個輕量級、高效能的物件對映庫,旨在簡化這些任務。相比於其他對映工具,Mapster 以其簡潔易用、靈活強大和高效能的特點在開發者中受到廣泛歡迎。

本文將深入講解 Mapster 的各種高階用法和應用場景,包括對映集合、巢狀物件、條件對映、自定義轉換等,幫助你更高效地進行物件轉換。


1. 安裝和基本用法

首先,確保你已透過 NuGet 安裝了 Mapster:

Install-Package Mapster

或者在 .NET 專案中使用以下命令:

dotnet add package Mapster

基本的物件對映

Mapster 的核心是 TypeAdapter 類,它提供了多種對映方法。最常用的方法是 Adapt(),它用於將一個物件對映到另一個物件。

using Mapster;
using System;

public class Source
{
public int Id { get; set; }
public string Name { get; set; }
}

public class Destination
{
public int Id { get; set; }
public string Name { get; set; }
}

public class Program
{
public static void Main()
{
var source = new Source { Id = 1, Name = "Mapster" };

// 對映
var destination = source.Adapt<Destination>();

Console.WriteLine($"Id: {destination.Id}, Name: {destination.Name}");
}
}

2. 對映集合型別

Mapster 允許將集合型別(如 List、Array 等)進行對映。例如,將 List<Source> 對映為 List<Destination>,Mapster 會自動遍歷集合並進行物件對映。

示例:對映 List 集合

using Mapster;
using System;
using System.Collections.Generic;

public class Source
{
public int Id { get; set; }
public string Name { get; set; }
}

public class Destination
{
public int Id { get; set; }
public string Name { get; set; }
}

public class Program
{
public static void Main()
{
var sourceList = new List<Source>
{
new Source { Id = 1, Name = "Alice" },
new Source { Id = 2, Name = "Bob" }
};

// 對映 List<Source> 到 List<Destination>
var destinationList = sourceList.Adapt<List<Destination>>();

foreach (var dest in destinationList)
{
Console.WriteLine($"Id: {dest.Id}, Name: {dest.Name}");
}
}
}

示例:對映 Array

public class Program
{
public static void Main()
{
var sourceArray = new Source[]
{
new Source { Id = 1, Name = "John" },
new Source { Id = 2, Name = "Jane" }
};

// 對映陣列
var destinationArray = sourceArray.Adapt<Destination[]>();

foreach (var dest in destinationArray)
{
Console.WriteLine($"Id: {dest.Id}, Name: {dest.Name}");
}
}
}

3. 巢狀物件對映

Mapster 支援巢狀物件的自動對映。例如,一個物件包含另一個物件作為屬性,Mapster 會遞迴地處理這些巢狀的物件。

示例:巢狀物件對映

public class Source
{
public int Id { get; set; }
public string Name { get; set; }
public Address Address { get; set; }
}

public class Address
{
public string Street { get; set; }
public string City { get; set; }
}

public class Destination
{
public int Id { get; set; }
public string Name { get; set; }
public AddressDto Address { get; set; }
}

public class AddressDto
{
public string Street { get; set; }
public string City { get; set; }
}

public class Program
{
public static void Main()
{
var source = new Source
{
Id = 1,
Name = "Alice",
Address = new Address
{
Street = "123 Elm Street",
City = "Wonderland"
}
};

// 自動對映巢狀物件
var destination = source.Adapt<Destination>();

Console.WriteLine($"Id: {destination.Id}, Name: {destination.Name}");
Console.WriteLine($"Street: {destination.Address.Street}, City: {destination.Address.City}");
}
}

4. 條件對映

Mapster 允許根據條件進行對映。例如,我們可以根據源物件的屬性值來決定目標屬性的對映值。

示例:條件對映

public class Source
{
public int Age { get; set; }
}

public class Destination
{
public string AgeCategory { get; set; }
}

public class Program
{
public static void Main()
{
var source = new Source { Age = 25 };

// 根據條件對映
var destination = source.Adapt<Destination>(config =>
config.Map(dest => dest.AgeCategory, src => src.Age >= 18 ? "Adult" : "Minor")
);

Console.WriteLine($"Age Category: {destination.AgeCategory}");
}
}

在這個例子中,AgeCategory 的值是根據 Age 的值進行對映的。如果 Age 大於等於 18,則對映為 "Adult",否則對映為 "Minor"

示例:使用條件進行自定義對映

public class Source
{
public bool IsActive { get; set; }
}

public class Destination
{
public string Status { get; set; }
}

public class Program
{
public static void Main()
{
var source = new Source { IsActive = true };

// 使用條件進行自定義對映
var destination = source.Adapt<Destination>(config =>
config.Map(dest => dest.Status, src => src.IsActive ? "Active" : "Inactive")
);

Console.WriteLine($"Status: {destination.Status}");
}
}

5. 自定義轉換邏輯

有時我們需要進行自定義的對映操作,比如根據某個欄位進行處理。Mapster 提供了 config.Map() 方法來實現這些自定義轉換。

示例:自定義轉換函式

public class Source
{
public string FullName { get; set; }
}

public class Destination
{
public string FirstName { get; set; }
public string LastName { get; set; }
}

public class Program
{
public static void Main()
{
var source = new Source { FullName = "John Doe" };

// 自定義轉換邏輯,將 FullName 拆分為 FirstName 和 LastName
var destination = source.Adapt<Destination>(config =>
config.Map(dest => dest.FirstName, src => src.FullName.Split(' ')[0])
.Map(dest => dest.LastName, src => src.FullName.Split(' ')[1])
);

Console.WriteLine($"First Name: {destination.FirstName}, Last Name: {destination.LastName}");
}
}

在這個例子中,FullName 被拆分為 FirstNameLastName。透過自定義轉換函式,你可以在對映過程中進行更多的資料處理。

6. 高階功能

Mapster 除了提供基礎的物件對映功能,還支援多種高階特性,幫助開發者在不同的應用場景中更高效地進行物件對映,提升效能和靈活性。以下是一些 Mapster 的高階功能:

1. 對映配置

在使用 Mapster 時,我們通常會對多個不同的類進行對映。如果每次對映時都要配置相同的對映規則,就顯得冗餘且容易出錯。Mapster 提供了全域性對映配置的功能,允許你預先定義對映規則,避免重複配置。

示例:全域性對映配置
using Mapster;
using System;

public class Source
{
public int Id { get; set; }
public string Name { get; set; }
}

public class Destination
{
public int Id { get; set; }
public string Name { get; set; }
}

public class Program
{
public static void Main()
{
// 全域性配置對映規則
TypeAdapterConfig<Source, Destination>.NewConfig()
.Map(dest => dest.Name, src => src.Name.ToUpper()); // 把 Name 欄位轉為大寫

var source = new Source { Id = 1, Name = "Mapster" };

// 使用已配置的全域性對映規則
var destination = source.Adapt<Destination>();

Console.WriteLine($"Id: {destination.Id}, Name: {destination.Name}"); // Name 會變成大寫
}
}

在這個例子中,我們透過 TypeAdapterConfig<Source, Destination>.NewConfig() 配置了一個全域性的對映規則,所有從 SourceDestination 的對映都會自動應用這個規則,確保 Name 欄位在對映過程中被轉換為大寫。這樣,當你處理多個物件對映時,不需要每次都重新配置對映規則。

2. 效能最佳化

Mapster 的設計使其在執行物件對映時具有極高的效能。Mapster 使用了程式碼生成技術,以避免傳統反射帶來的效能開銷。在預設情況下,Mapster 會使用反射進行對映,但你可以啟用程式碼生成來進一步提高效能。

啟用程式碼生成

為了啟用程式碼生成,你只需要在專案中安裝 Mapster.Generator 包:

Install-Package Mapster.Generator

啟用程式碼生成後,Mapster 會在編譯時生成原始碼,代替執行時反射,極大提升對映速度。

dotnet build

然後你就可以在專案中使用 Mapster 的高效能對映,而不必擔心效能瓶頸。

3. 支援集合型別的對映

Mapster 不僅支援單個物件之間的對映,還能自動處理集合型別(如 ListArrayIEnumerable 等)。當你需要將一個集合中的每個元素對映到另一個集合時,Mapster 會自動遍歷集合並進行逐一對映。

示例:對映 List 集合
using Mapster;
using System;
using System.Collections.Generic;

public class Source
{
public int Id { get; set; }
public string Name { get; set; }
}

public class Destination
{
public int Id { get; set; }
public string Name { get; set; }
}

public class Program
{
public static void Main()
{
var sourceList = new List<Source>
{
new Source { Id = 1, Name = "Alice" },
new Source { Id = 2, Name = "Bob" }
};

// 對映 List<Source> 到 List<Destination>
var destinationList = sourceList.Adapt<List<Destination>>();

foreach (var dest in destinationList)
{
Console.WriteLine($"Id: {dest.Id}, Name: {dest.Name}");
}
}
}

在這個例子中,Mapster 會自動將 List<Source> 對映為 List<Destination>。透過使用 Adapt<List<Destination>>(),Mapster 會逐個對映 Source 列表中的元素。

4. 並行對映

在處理大量資料時,Mapster 還提供了並行對映的支援。透過並行對映,可以加速資料轉換過程,特別是在多核處理器上,能夠顯著提高效能。

示例:並行對映
using Mapster;
using System;
using System.Collections.Generic;
using System.Linq;

public class Source
{
public int Id { get; set; }
public string Name { get; set; }
}

public class Destination
{
public int Id { get; set; }
public string Name { get; set; }
}

public class Program
{
public static void Main()
{
var sourceList = new List<Source>
{
new Source { Id = 1, Name = "Alice" },
new Source { Id = 2, Name = "Bob" },
new Source { Id = 3, Name = "Charlie" }
};

// 使用並行對映
var destinationList = sourceList.AsParallel().Adapt<List<Destination>>();

foreach (var dest in destinationList)
{
Console.WriteLine($"Id: {dest.Id}, Name: {dest.Name}");
}
}
}

在這個例子中,我們使用了 AsParallel() 方法將 List<Source> 轉換為並行序列。透過這種方式,Mapster 會並行執行對映操作,極大地加速了大資料集的對映過程。需要注意的是,並行對映適合於處理計算密集型的對映任務,但對於簡單的對映任務,使用並行可能並不會帶來明顯的效能提升,反而可能增加額外的執行緒排程開銷。

總結

Mapster 是一款高效、靈活且易用的物件對映工具,適用於多種場景。本文介紹了從基礎的物件對映到高階特性(如集合對映、巢狀對映、條件對映、自定義轉換等)的各種用法,幫助你在實際開發中更加高效地處理物件對映任務。

無論是在多層架構的專案中處理 DTO 和實體類的轉換,還是在跨系統的資料交換中進行資料對映,Mapster 都能夠提供強大而簡潔的解決方案。如果你正在尋找一款高效的物件對映庫,Mapster無疑是一個值得嘗試的好選擇。

相關文章