-
Notifications
You must be signed in to change notification settings - Fork 6
Home
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.
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.
- 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.
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 |
To include mapping functionality in your project, just install the MapTo nuget package.
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.