Skip to content
Mohammadreza edited this page Oct 14, 2023 · 4 revisions

What is MapTo?

MapTo is a C# library that enables you to map objects without utilizing reflection or separate mapping classes. It utilizes the Roslyn source generator for compiling the mapping code, which enhances speed and safety. You can customize the mapping behaviour using attributes and create mapped objects using extension methods, constructors, or factory methods.

What is object mapping?

When working with data transfer objects (DTOs) in layered architectures, object mapping is a common task that involves transforming an object of one type into another type.

One of the challenges is the time-consuming and error-prone process of manually mapping objects. Developers have to write a significant amount of boilerplate code to map each property from the source object to the destination object. This becomes even more complex for nested properties and different data types.

Another challenge is maintaining this code, which can be difficult when adding, removing, or changing a property in either the source or destination class. The mapping code needs to be updated accordingly, or it can result in bugs.

Using reflection for object mapping at runtime can impact performance, which can affect the overall performance of the application. Reflection is a process that allows code to inspect other code within the same system (or itself) at runtime. However, it can be slow and consume more memory.

Why use MapTo?

  • No need to write and maintain boilerplate code by hand
  • MapTo creates mappings during build time or in the IDE as you write code.
  • MapTo is AoT-compatible due to its non-use of reflection.
  • There are no runtime dependencies associated with MapTo or its generated codes.
  • The generated mappings are both fast and memory-efficient while remaining easily readable and debuggable.

Performance

MapTo is a high-speed .NET object mapper, outperforming even manual mapping. The table below compares its performance to other mapping libraries. Benchmark Source

Method Mean Error StdDev Gen 0 Gen 1 Allocated
MapTo 190.3 ns 3.75 ns 4.88 ns 0.1466 0.0005 920 B
Mapperly 195.5 ns 3.73 ns 3.31 ns 0.1466 0.0005 920 B
ManualMapping 302.8 ns 1.57 ns 1.23 ns 0.1845 0.0005 1160 B
Mapster 324.5 ns 6.49 ns 10.10 ns 0.3033 0.0014 1904 B
AutoMapper 860.0 ns 9.59 ns 8.01 ns 0.3033 0.0010 1904 B
TinyMapper 2,127.9 ns 13.35 ns 10.42 ns 0.3433 - 2160 B

Installation

To include mapping functionality in your project, just install the MapTo nuget package.

Nuget

How to use MapTo

Unlike other libraries that require a separate class to define the mappings, MapTo uses attributes to define and configure the generated mappings. To start, declare the target class and annotate it with the MapFrom attribute to specify the source class.

namespace MyApp.Models;

public class User
{
    public int Id { get; set; }

    public string FirstName { get; set; }

    public string LastName { get; set; }
}
using MapTo;
using MyApp.Models

namespace MyApp.ViewModels;

[MapFrom(typeof(User))]
public class UserViewModel 
{
    public int Id { get; init; }

    public string FirstName { get; init; }

    public string? LastName { get; set; }   
}

The MapTo method generates an extension method called MapToUserViewModel that maps the User model (source) to the UserViewModel (target). It can be used as follows:

var user = new User
{
    Id = 1,
    FirstName = "John",
    LastName = "Doe"
};

var userViewModel = user.MapToUserViewModel();

When you go to the MapToUserViewModel extension method implementation, you will see this generated class:

namespace MyApp.Models;

[global::System.CodeDom.Compiler.GeneratedCodeAttribute("MapTo", "0.9.1.59089")]
public static class UserMapToExtensions
{
    [return: global::System.Diagnostics.CodeAnalysis.NotNullIfNotNull("user")]
    public static UserViewModel? MapToUserViewModel(this User? user)
    {
        if (ReferenceEquals(user, null))
        {
            return null;
        }

        return new UserViewModel
        {
            Id = user.Id,
            FirstName = user.FirstName,
            LastName = user.LastName
        };
    }
}

💡 The MapTo can intelligently apply values using constructors, object initializers, or property setters. More information on these later.

Clone this wiki locally