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.
- Static
- Instance
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);
}
To use the mappings of an object instance UseMapper can be used:
[Mapper]
public static partial class BoxMapper
{
[UseMapper]
private readonly BananaMapper _bananaMapper = new();
public static partial BananaBox MapBananaBox(BananaBoxDto dto);
}
public static class BananaMapper
{
public static Banana MapBanana(BananaDto dto)
=> new Banana(dto.Weight);
}
The initialization of fields and properties annotated with UseMapper needs to be done by the user.
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.
- Use with fullnameof
- Use with string path
- Other mapper class
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();
}
namespace MyNamespace;
[Mapper]
public partial class CarMapper
{
[MapProperty(nameof(Car.Price), nameof(CarDto.Price), Use = "OtherNamespace.PriceMapper.MapPrice")]
[MapPropertyFromSource(nameof(CarDto.NetPrice), Use = "OtherNamespace.PriceMapper.MapPriceFromSource")]
[MapValue(nameof(CarDto.SourceSystem), Use = "OtherNamespace.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();
}
namespace OtherNamespace;
public static class PriceMapper
{
public static string MapPrice(decimal price)
=> (price / 100).ToString("C");
public static string MapPriceFromSource(Car source)
=> (source.Price / 100).ToString("C");
}
public static class SourceSystems
{
public static string GetSourceSystem() => "C1";
}
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.
- Instance with fullnameof
- Instance with string path
- Price mapper class
[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();
}
[Mapper]
public partial class CarMapper
{
public PriceMapper PriceMapper { get; } = new();
public SourceSystems SourceSystems { get; } = new();
[MapProperty(nameof(Car.Price), nameof(CarDto.Price), Use = "PriceMapper.MapPrice")]
[MapPropertyFromSource(nameof(CarDto.NetPrice), Use = "PriceMapper.MapPriceFromSource")]
[MapValue(nameof(CarDto.SourceSystem), Use = "SourceSystems.GetSourceSystem")]
public partial CarDto MapCar(Car source);
// generates
target.Price = PriceMapper.MapPrice(source.Price);
target.NetPrice = PriceMapper.MapPriceFromSource(source);
target.SourceSystem = SourceSystems.GetSourceSystem();
}
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
{
public static string GetSourceSystem() => "C1";
}
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";
}