본문 바로가기
최신 IT

.NET 고성능 객체 매퍼, Mapster로 개발 속도 높이기

by 구라100단 2025. 9. 22.

.NET 개발에서 객체 매핑은 여러 계층 간에 데이터를 원활하게 전송하기 위한 필수적인 작업입니다. 예를 들어, 도메인 엔티티를 API 응답을 위한 DTO(Data Transfer Object)로 변환하는 경우가 대표적이죠. 이러한 변환 작업을 수동으로 처리하는 것은 번거롭고 오류가 발생하기 쉽습니다.

이때 객체 매핑 라이브러리가 유용하게 사용됩니다. 오랫동안 .NET 커뮤니티에서는 AutoMapper가 사실상의 표준처럼 사용되어 왔지만, 최근에는 더 뛰어난 성능과 편의성을 자랑하는 Mapster가 새로운 강자로 떠오르며 많은 개발자들의 주목을 받고 있습니다.

이번 포스팅에서는 Mapster가 왜 뛰어난 선택인지, 그리고 ASP.NET Core 프로젝트에 어떻게 적용할 수 있는지 자세히 알아보겠습니다.


Mapster란 무엇인가요?

Mapster는 .NET을 위한 고성능의 오픈소스 객체-객체 매핑 라이브러리입니다. 다음과 같은 강력한 장점들을 가지고 있습니다.

  • ⚡️ 압도적인 성능: Mapster는 뛰어난 속도와 메모리 효율성을 자랑합니다. 내부적으로 동적 코드 생성을 통해 수동 매핑에 가까운 성능을 보여주어, 애플리케이션의 전반적인 응답성을 향상시킵니다.
  • 🧩 유연성과 간편함: 복잡한 설정 없이도 직관적으로 사용할 수 있으며, 다양한 매핑 시나리오를 손쉽게 처리할 수 있는 유연성을 제공합니다.
  • 🔧 쉬운 설정: 의존성 주입(Dependency Injection)을 통한 깔끔한 설정이 가능하여 프로젝트에 통합하기 매우 용이합니다.

ASP.NET Core에서 Mapster 시작하기

이제 실제 ASP.NET Core 프로젝트에 Mapster를 설치하고 사용하는 방법을 단계별로 살펴보겠습니다.

1. Mapster 설치

먼저 NuGet 패키지 관리자를 통해 Mapster를 설치합니다. 의존성 주입을 함께 사용하기 위해 Mapster.DependencyInjection도 설치해 줍니다.

dotnet add package Mapster
dotnet add package Mapster.DependencyInjection

2. 기본 매핑 설정

Mapster는 별도의 설정 없이도 이름이 같은 프로퍼티를 자동으로 매핑해 줍니다. 예를 들어, 다음과 같은 User 엔티티와 UserDto가 있다고 가정해 봅시다.

public class User
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Email { get; set; }
}

public class UserDto
{
    public int Id { get; set; }
    public string FullName { get; set; }
    public string Email { get; set; }
}

User 객체를 UserDto로 변환하려면 Adapt 확장 메서드를 사용하기만 하면 됩니다.

var user = new User { Id = 1, FirstName = "John", LastName = "Doe", Email = "john.doe@example.com" };

// User를 UserDto로 변환
var userDto = user.Adapt<UserDto>();

하지만 위 코드에서 UserDtoFullName 프로퍼티는 UserFirstNameLastName을 조합해야 하므로 추가 설정이 필요합니다.

3. 의존성 주입 및 커스텀 매핑 설정

Program.cs 파일에 Mapster 설정을 추가하여 의존성 주입을 구성하고 커스텀 매핑 규칙을 정의할 수 있습니다.

var builder = WebApplication.CreateBuilder(args);

// TypeAdapterConfig를 싱글턴으로 등록
var config = new TypeAdapterConfig();
builder.Services.AddSingleton(config);

// IMapper 서비스를 추가
builder.Services.AddScoped<IMapper, ServiceMapper>();

// 커스텀 매핑 규칙 정의
config.NewConfig<User, UserDto>()
    .Map(dest => dest.FullName, src => $"{src.FirstName} {src.LastName}");


var app = builder.Build();

이제 컨트롤러 등에서 IMapper를 주입받아 매핑을 수행할 수 있습니다.

[ApiController]
[Route("[controller]")]
public class UsersController : ControllerBase
{
    private readonly IMapper _mapper;

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

    [HttpGet]
    public IActionResult GetUser()
    {
        var user = new User { Id = 1, FirstName = "Jane", LastName = "Doe", Email = "jane.doe@example.com" };

        // IMapper를 통해 매핑 수행
        var userDto = _mapper.Map<UserDto>(user);

        return Ok(userDto); // 결과: { "Id": 1, "FullName": "Jane Doe", "Email": "jane.doe@example.com" }
    }
}

고급 매핑 시나리오

Mapster는 단순한 프로퍼티 매핑 외에 더 복잡한 시나리오도 효과적으로 처리합니다.

  • 객체 평탄화 (Flattening): 중첩된 객체의 프로퍼티를 상위 DTO로 쉽게 매핑할 수 있습니다.
  • 쿼리 프로젝션 (Queryable Projections): 데이터베이스에서 데이터를 조회할 때 필요한 컬럼만 선택적으로 가져오는 SELECT 문을 자동으로 생성하여 성능을 최적화합니다. 이는 Entity Framework Core와 함께 사용할 때 특히 강력한 기능입니다.

Mapster vs. AutoMapper

두 라이브러리를 간단히 비교하면 다음과 같습니다.

구분 Mapster AutoMapper
성능 매우 뛰어남 (속도 및 메모리 효율성) 상대적으로 느림
설정 간단하고 직관적 다소 복잡할 수 있음
커뮤니티 성장 중 거대하고 성숙한 커뮤니티

AutoMapper는 오랜 기간 동안 많은 프로젝트에서 사용되어 온 만큼 방대한 자료와 거대한 커뮤니티를 가지고 있습니다. 하지만 순수한 성능과 간결한 설정을 우선시한다면 Mapster는 단연코 최고의 선택이 될 것입니다.

결론

Mapster는 .NET 생태계에 등장한 강력하고 효율적인 객체 매핑 라이브러리입니다. 뛰어난 성능, 직관적인 사용법, 그리고 유연한 구성 방식을 통해 개발자가 반복적인 매핑 코드 작성에서 벗어나 비즈니스 로직에 더 집중할 수 있도록 돕습니다.

새로운 .NET 프로젝트를 시작하거나 기존 프로젝트의 성능 개선을 고민하고 있다면, Mapster를 도입해 보시는 것을 추천합니다.