Skip to main content

Generated mapper example

This example will show you what kind of code Mapperly generates. It is based on the Mapperly sample. To view the generated code of your own mapper, refer to the generated source configuration.

The source classes

In this example, we have a car class with some general information.

namespace Riok.Mapperly.Sample;

public class Car
{
public string Name { get; set; } = string.Empty;

public int NumberOfSeats { get; set; }

public CarColor Color { get; set; }

public Manufacturer? Manufacturer { get; set; }

public List<Tire> Tires { get; } = new List<Tire>();
}

public enum CarColor
{
Black = 1,
Blue = 2,
White = 3,
}

public class Manufacturer
{
public Manufacturer(int id, string name)
{
Id = id;
Name = name;
}

public int Id { get; }

public string Name { get; }
}

public class Tire
{
public string Description { get; set; } = string.Empty;
}

The target classes

Our sample target classes are mostly the same as the source classes. For demonstration purposes, we named the manufacturer property differently to show how Mapperly can handle this use case.

namespace Riok.Mapperly.Sample;

public class CarDto
{
public string Name { get; set; } = string.Empty;

public int NumberOfSeats { get; set; }

public CarColorDto Color { get; set; }

public ProducerDto? Producer { get; set; }

public List<TireDto>? Tires { get; set; }
}

// Intentionally use different numeric values for demonstration purposes
public enum CarColorDto
{
Yellow = 1,
Green = 2,
Black = 3,
Blue = 4,
}

// The manufacturer, but named differently for demonstration purposes
public class ProducerDto
{
public ProducerDto(int id, string name)
{
Id = id;
Name = name;
}

public int Id { get; }

public string Name { get; }
}

public class TireDto
{
public string Description { get; set; } = string.Empty;
}

The mapper

The actual mapper is pretty simple. We use a static mapper class in this example. As usual, we need to mark the mapper with the [Mapper] attribute, so that the source generator is able to recognize it. Because the manufacturer/producer properties are named differently, we also need to configure that via an attribute. In addition, because the CarColor and CarColorDto entries have different numeric values, we need to configure Mapperly to map them by their name.

using Riok.Mapperly.Abstractions;

namespace Riok.Mapperly.Sample;

// Enums of source and target have different numeric values -> use ByName strategy to map them
[Mapper(EnumMappingStrategy = EnumMappingStrategy.ByName)]
public static partial class CarMapper
{
[MapProperty(nameof(Car.Manufacturer), nameof(CarDto.Producer))] // Map property with a different name in the target type
public static partial CarDto MapCarToDto(Car car);
}

The generated code

// <auto-generated />
#nullable enable
namespace Riok.Mapperly.Sample
{
public static partial class CarMapper
{
[global::System.CodeDom.Compiler.GeneratedCode("Riok.Mapperly", "0.0.1.0")]
public static partial global::Riok.Mapperly.Sample.CarDto MapCarToDto(global::Riok.Mapperly.Sample.Car car)
{
var target = new global::Riok.Mapperly.Sample.CarDto();
if (car.Manufacturer != null)
{
target.Producer = MapToProducerDto(car.Manufacturer);
}
else
{
target.Producer = null;
}
target.Name = car.Name;
target.NumberOfSeats = car.NumberOfSeats;
target.Color = MapToCarColorDto(car.Color);
target.Tires = MapToListOfTireDto(car.Tires);
return target;
}

[global::System.CodeDom.Compiler.GeneratedCode("Riok.Mapperly", "0.0.1.0")]
private static global::Riok.Mapperly.Sample.CarColorDto MapToCarColorDto(global::Riok.Mapperly.Sample.CarColor source)
{
return source switch
{
global::Riok.Mapperly.Sample.CarColor.Black => global::Riok.Mapperly.Sample.CarColorDto.Black,
global::Riok.Mapperly.Sample.CarColor.Blue => global::Riok.Mapperly.Sample.CarColorDto.Blue,
_ => throw new System.ArgumentOutOfRangeException(nameof(source), source, "The value of enum CarColor is not supported"),
};
}

[global::System.CodeDom.Compiler.GeneratedCode("Riok.Mapperly", "0.0.1.0")]
private static global::Riok.Mapperly.Sample.ProducerDto MapToProducerDto(global::Riok.Mapperly.Sample.Manufacturer source)
{
var target = new global::Riok.Mapperly.Sample.ProducerDto(source.Id, source.Name);
return target;
}

[global::System.CodeDom.Compiler.GeneratedCode("Riok.Mapperly", "0.0.1.0")]
private static global::Riok.Mapperly.Sample.TireDto MapToTireDto(global::Riok.Mapperly.Sample.Tire source)
{
var target = new global::Riok.Mapperly.Sample.TireDto();
target.Description = source.Description;
return target;
}

[global::System.CodeDom.Compiler.GeneratedCode("Riok.Mapperly", "0.0.1.0")]
private static global::System.Collections.Generic.List<global::Riok.Mapperly.Sample.TireDto> MapToListOfTireDto(global::System.Collections.Generic.IReadOnlyCollection<global::Riok.Mapperly.Sample.Tire> source)
{
var target = new global::System.Collections.Generic.List<global::Riok.Mapperly.Sample.TireDto>(source.Count);
foreach (var item in source)
{
target.Add(MapToTireDto(item));
}
return target;
}
}
}