DotNet開發

前言

.NET 的生態每年都在變,同一件事常常有好幾種做法。這篇整理實務上常遇到的兩個選擇:部署時要用 JIT 還是 Native AOT,以及物件映射該用手寫、AutoMapper 還是 Mapperly。

此篇文章以 .NET 8 以後的版本為主做說明。

部署架構

JIT(Just-In-Time)與 Native AOT(Ahead-Of-Time,提前編譯)的差異。

Native AOT 從 .NET 7 開始提供,但當時只支援主控台應用程式;到了 .NET 8 才支援 ASP.NET Core(Minimal API、gRPC),一般 Web API 專案要 .NET 8 以上才能使用。

觀點 一般的 JIT 執行 Native AOT
執行階段 JIT 使用 不使用
發佈產物 以 IL中繼語言 為主 以原生執行檔為主
啟動 基準 相當容易改善
相容性 最廣 限制較強
動態功能 好用 限制很多
適合的目的 一般的 .NET 開發 想強力拿下啟動、散發(部署)與受限環境

物件映射(Object Mapping)

方式 執行效率 開發速度 Debug難易度 編譯時期檢查 支援 Native AOT 適用場景
手寫 極快 最慢 極易 ✅ ✅ 效能要求高、欄位經常變動、或是中小型專案規模
AutoMapper 比手寫慢 快 困難 ❌ ❌ AutoMapper 從 2025 年的 15 版開始改成商業授權,商用需要買授權。
Mapperly 極快 快 易 ✅ ✅ 想要手寫的效能,又不想手動寫一堆 A = B 的大型專案

一、AutoMapper

1.註冊

services.AddAutoMapper(assemblies);

CreateMap<Model1, Model2>()
.ForMember(d => d.Age, o => o.MapFrom(s => s.age));

2.使用

private readonly IMapper _mapper;

public Test(IMapper mapper)
{
    _mapper = mapper;
}

var resModel = _mapper.Map<ResModel>(resDto);

目前已知的Bug

10.1.1版以前(含),針對空值轉DateTime,會預設塞DateTime.MinValue。

但10.1.1以後的版本,針對空值轉日期,會出現 AutoMapperMappingException的錯誤。

二、Mapperly

1.設定

新增Mapper的partial class

[Mapper(PropertyNameMappingStrategy = PropertyNameMappingStrategy.CaseInsensitive)]
public partial class UserMapper
{
    // 編譯器會自動實作這個方法
    // 指定對應欄位
    //[MapProperty(nameof(Model1.age), nameof(Model2.Age))]
    public partial Model2 MapToModel2(Model1 model1);
}

備註:

(1)如果欄位對應想忽略大小寫,類別的Attribute 改成 [Mapper(PropertyNameMappingStrategy = PropertyNameMappingStrategy.CaseInsensitive)] 否則只要 [Mapper] 就好。

(2)欄位若名稱不一致,在方法的Attribute新增 MapProperty。

2.註冊

services.AddSingleton<UserMapper>();

3.從 DI取出後使用

private readonly UserMapper _userMapper;

public Test(UserMapper userMapper)
{
    _userMapper = userMapper;
}

Model1 model1 = new Model1() { age = "30", assets = "1000.50", name = "John Doe", birth = "1990-01-01" };
Model2 model2 = _userMapper.MapToModel2(model1);