Mapster 高級(jí)功能解析:高效對(duì)象映射與優(yōu)化技巧
在現(xiàn)代開發(fā)中,對(duì)象之間的轉(zhuǎn)換是常見且繁瑣的任務(wù),尤其是在多層架構(gòu)或跨系統(tǒng)數(shù)據(jù)傳輸?shù)膱?chǎng)景下。Mapster 是一個(gè)輕量級(jí)、高性能的對(duì)象映射庫,旨在簡(jiǎn)化這些任務(wù)。相比于其他映射工具,Mapster 以其簡(jiǎn)潔易用、靈活強(qiáng)大和高性能的特點(diǎn)在開發(fā)者中受到廣泛歡迎。
本文將深入講解 Mapster 的各種高級(jí)用法和應(yīng)用場(chǎng)景,包括映射集合、嵌套對(duì)象、條件映射、自定義轉(zhuǎn)換等,幫助你更高效地進(jìn)行對(duì)象轉(zhuǎn)換。
1. 安裝和基本用法
首先,確保你已通過 NuGet 安裝了 Mapster:
Install-Package Mapster
或者在 .NET 項(xiàng)目中使用以下命令:
dotnet add package Mapster
基本的對(duì)象映射
Mapster 的核心是 TypeAdapter 類,它提供了多種映射方法。最常用的方法是 Adapt(),它用于將一個(gè)對(duì)象映射到另一個(gè)對(duì)象。
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 等)進(jìn)行映射。例如,將 List<Source> 映射為 List<Destination>,Mapster 會(huì)自動(dòng)遍歷集合并進(jìn)行對(duì)象映射。
示例:映射 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" }
};
?
// 映射數(shù)組
var destinationArray = sourceArray.Adapt<Destination[]>();
?
foreach (var dest in destinationArray)
{
Console.WriteLine($"Id: {dest.Id}, Name: {dest.Name}");
}
}
}
3. 嵌套對(duì)象映射
Mapster 支持嵌套對(duì)象的自動(dòng)映射。例如,一個(gè)對(duì)象包含另一個(gè)對(duì)象作為屬性,Mapster 會(huì)遞歸地處理這些嵌套的對(duì)象。
示例:嵌套對(duì)象映射
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"
}
};
?
// 自動(dòng)映射嵌套對(duì)象
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 允許根據(jù)條件進(jìn)行映射。例如,我們可以根據(jù)源對(duì)象的屬性值來決定目標(biāo)屬性的映射值。
示例:條件映射
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 };
?
// 根據(jù)條件映射
var destination = source.Adapt<Destination>(config =>
config.Map(dest => dest.AgeCategory, src => src.Age >= 18 ? "Adult" : "Minor")
);
?
Console.WriteLine($"Age Category: {destination.AgeCategory}");
}
}
在這個(gè)例子中,AgeCategory 的值是根據(jù) Age 的值進(jìn)行映射的。如果 Age 大于等于 18,則映射為 "Adult",否則映射為 "Minor"。
示例:使用條件進(jìn)行自定義映射
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 };
?
// 使用條件進(jìn)行自定義映射
var destination = source.Adapt<Destination>(config =>
config.Map(dest => dest.Status, src => src.IsActive ? "Active" : "Inactive")
);
?
Console.WriteLine($"Status: {destination.Status}");
}
}
5. 自定義轉(zhuǎn)換邏輯
有時(shí)我們需要進(jìn)行自定義的映射操作,比如根據(jù)某個(gè)字段進(jìn)行處理。Mapster 提供了 config.Map() 方法來實(shí)現(xiàn)這些自定義轉(zhuǎn)換。
示例:自定義轉(zhuǎn)換函數(shù)
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" };
?
// 自定義轉(zhuǎn)換邏輯,將 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}");
}
}
在這個(gè)例子中,FullName 被拆分為 FirstName 和 LastName。通過自定義轉(zhuǎn)換函數(shù),你可以在映射過程中進(jìn)行更多的數(shù)據(jù)處理。
6. 高級(jí)功能
Mapster 除了提供基礎(chǔ)的對(duì)象映射功能,還支持多種高級(jí)特性,幫助開發(fā)者在不同的應(yīng)用場(chǎng)景中更高效地進(jìn)行對(duì)象映射,提升性能和靈活性。以下是一些 Mapster 的高級(jí)功能:
1. 映射配置
在使用 Mapster 時(shí),我們通常會(huì)對(duì)多個(gè)不同的類進(jìn)行映射。如果每次映射時(shí)都要配置相同的映射規(guī)則,就顯得冗余且容易出錯(cuò)。Mapster 提供了全局映射配置的功能,允許你預(yù)先定義映射規(guī)則,避免重復(fù)配置。
示例:全局映射配置
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()
{
// 全局配置映射規(guī)則
TypeAdapterConfig<Source, Destination>.NewConfig()
.Map(dest => dest.Name, src => src.Name.ToUpper()); // 把 Name 字段轉(zhuǎn)為大寫
?
var source = new Source { Id = 1, Name = "Mapster" };
// 使用已配置的全局映射規(guī)則
var destination = source.Adapt<Destination>();
?
Console.WriteLine($"Id: {destination.Id}, Name: {destination.Name}"); // Name 會(huì)變成大寫
}
}
在這個(gè)例子中,我們通過 TypeAdapterConfig<Source, Destination>.NewConfig() 配置了一個(gè)全局的映射規(guī)則,所有從 Source 到 Destination 的映射都會(huì)自動(dòng)應(yīng)用這個(gè)規(guī)則,確保 Name 字段在映射過程中被轉(zhuǎn)換為大寫。這樣,當(dāng)你處理多個(gè)對(duì)象映射時(shí),不需要每次都重新配置映射規(guī)則。
2. 性能優(yōu)化
Mapster 的設(shè)計(jì)使其在執(zhí)行對(duì)象映射時(shí)具有極高的性能。Mapster 使用了代碼生成技術(shù),以避免傳統(tǒng)反射帶來的性能開銷。在默認(rèn)情況下,Mapster 會(huì)使用反射進(jìn)行映射,但你可以啟用代碼生成來進(jìn)一步提高性能。
啟用代碼生成
為了啟用代碼生成,你只需要在項(xiàng)目中安裝 Mapster.Generator 包:
Install-Package Mapster.Generator
啟用代碼生成后,Mapster 會(huì)在編譯時(shí)生成源代碼,代替運(yùn)行時(shí)反射,極大提升映射速度。
dotnet build
然后你就可以在項(xiàng)目中使用 Mapster 的高性能映射,而不必?fù)?dān)心性能瓶頸。
3. 支持集合類型的映射
Mapster 不僅支持單個(gè)對(duì)象之間的映射,還能自動(dòng)處理集合類型(如 List、Array、IEnumerable 等)。當(dāng)你需要將一個(gè)集合中的每個(gè)元素映射到另一個(gè)集合時(shí),Mapster 會(huì)自動(dòng)遍歷集合并進(jìn)行逐一映射。
示例:映射 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}");
}
}
}
在這個(gè)例子中,Mapster 會(huì)自動(dòng)將 List<Source> 映射為 List<Destination>。通過使用 Adapt<List<Destination>>(),Mapster 會(huì)逐個(gè)映射 Source 列表中的元素。
4. 并行映射
在處理大量數(shù)據(jù)時(shí),Mapster 還提供了并行映射的支持。通過并行映射,可以加速數(shù)據(jù)轉(zhuǎn)換過程,特別是在多核處理器上,能夠顯著提高性能。
示例:并行映射
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}");
}
}
}
在這個(gè)例子中,我們使用了 AsParallel() 方法將 List<Source> 轉(zhuǎn)換為并行序列。通過這種方式,Mapster 會(huì)并行執(zhí)行映射操作,極大地加速了大數(shù)據(jù)集的映射過程。需要注意的是,并行映射適合于處理計(jì)算密集型的映射任務(wù),但對(duì)于簡(jiǎn)單的映射任務(wù),使用并行可能并不會(huì)帶來明顯的性能提升,反而可能增加額外的線程調(diào)度開銷。
總結(jié)
Mapster 是一款高效、靈活且易用的對(duì)象映射工具,適用于多種場(chǎng)景。本文介紹了從基礎(chǔ)的對(duì)象映射到高級(jí)特性(如集合映射、嵌套映射、條件映射、自定義轉(zhuǎn)換等)的各種用法,幫助你在實(shí)際開發(fā)中更加高效地處理對(duì)象映射任務(wù)。

浙公網(wǎng)安備 33010602011771號(hào)