Skip to main content

Use external mappings

External mapping with UseMapper / UseStaticMapper

Mapperly can also consider mappings implemented in other classes. In order for Mapperly to find the mappings, they must be made known with UseMapper / UseStaticMapper.

For static mappings, UseStaticMapper can be used:

[Mapper]
[UseStaticMapper(typeof(BananaMapper))]
public static partial class BoxMapper
{
public static partial BananaBox MapBananaBox(BananaBoxDto dto);
}

public static class BananaMapper
{
public static Banana MapBanana(BananaDto dto)
=> new Banana(dto.Weight);
}

Whenever Mapperly needs a mapping from BananaBox to BananaBoxDto inside the BoxMapper implementation, it will use the provided implementation by the BananaMapper.

Used mappers themselves can be Mapperly backed classes.
The AutoUserMappings value also applies to the usage of external mappers.

External method reference

Static external method reference

Mapperly also supports referencing methods directly from an external class. To do this, prefix the path with @ in the Use property (see also full-nameof). This applies for MapProperty, MapPropertyFromSource and MapValue. It is also possible to use a string reference of the type. In this case the type must be fully qualified.

using OtherNamespace;

namespace MyNamespace;

[Mapper]
public partial class CarMapper
{
[MapProperty(nameof(Car.Price), nameof(CarDto.Price), Use = nameof(@PriceMapper.MapPrice))]
[MapPropertyFromSource(nameof(CarDto.NetPrice), Use = nameof(@PriceMapper.MapPriceFromSource))]
[MapValue(nameof(CarDto.SourceSystem), Use = nameof(@SourceSystems.GetSourceSystem))]
public partial CarDto MapCar(Car source);

// generates
target.Price = global::OtherNamespace.PriceMapper.MapPrice(source.Price);
target.NetPrice = global::OtherNamespace.PriceMapper.MapPriceFromSource(source);
target.SourceSystem = global::OtherNamespace.SourceSystems.GetSourceSystem();
}

Instance external method reference

It is also possible to use this syntax to reference instance methods if the mapper class has a property or field referencing the external type. In this case, the method should be referenced through this member.

[Mapper]
public partial class CarMapper
{
public PriceMapper PriceMapper { get; } = new();
public SourceSystems SourceSystems { get; } = new();

[MapProperty(nameof(Car.Price), nameof(CarDto.Price), Use = nameof(@PriceMapper.MapPrice))]
[MapPropertyFromSource(nameof(CarDto.NetPrice), Use = nameof(@PriceMapper.MapPriceFromSource))]
[MapValue(nameof(CarDto.SourceSystem), Use = nameof(@SourceSystems.GetSourceSystem))]
public partial CarDto MapCar(Car source);

// generates
target.Price = PriceMapper.MapPrice(source.Price);
target.NetPrice = PriceMapper.MapPriceFromSource(source);
target.SourceSystem = SourceSystems.GetSourceSystem();
}

Named mapping

The NamedMapping attribute can also be used in combination with the external method reference.

namespace MyNamespace;

[Mapper]
public partial class CarMapper
{
[MapProperty(nameof(Car.Price), nameof(CarDto.Price), Use = "PriceMapper.CustomMapPrice")]
[MapPropertyFromSource(nameof(CarDto.NetPrice), Use = "PriceMapper.CustomMapPriceFromSource")]
[MapValue(nameof(CarDto.SourceSystem), Use = "OtherNamespace.SourceSystems.CustomGetSourceSystem")]
public partial CarDto Map(Car car);

// generates
target.Price = PriceMapper.MapPrice(source.Price);
target.NetPrice = PriceMapper.MapPriceFromSource(source);
target.SourceSystem = SourceSystems.GetSourceSystem();
}
namespace OtherNamespace;

public class PriceMapper
{
public string MapPrice(decimal price)
=> (price / 100).ToString("C");

public string MapPriceFromSource(Car source)
=> (source.Price / 100).ToString("C");
}

public static class SourceSystems
{
[NamedMapping("CustomGetSourceSystem")]
public static string GetSourceSystem() => "C1";
}