Skip to main content

Mapper configuration

The MapperAttribute provides options to customize the generated mapper class.

Default Mapper configuration

The MapperDefaultsAttribute allows to set default configurations applied to all mappers on the assembly level.

[assembly: MapperDefaults(EnumMappingIgnoreCase = true)]

Copy behavior

By default, Mapperly does not create deep copies of objects to improve performance. If an object can be directly assigned to the target, it will do so (eg. if the source and target type are both Car[], the array and its entries will not be cloned). To create deep copies, set the UseDeepCloning property on the MapperAttribute to true.

[Mapper(UseDeepCloning = true)]
public partial class CarMapper
{
...
}

Properties / fields

On each mapping method declaration, property and field mappings can be customized. If a property or field on the target has a different name than on the source, the MapPropertyAttribute can be applied. See also the documentation on flattening / unflattening.

[Mapper]
public partial class CarMapper
{
[MapProperty(nameof(Car.Model), nameof(CarDto.ModelName))]
public partial CarDto ToDto(Car car);
}

Mapping from source

The source object itself can be mapped to a property of the target object with the MapPropertyFromSource attribute:

[Mapper]
public partial class CarMapper
{
[MapPropertyFromSource(nameof(CarChanges.OriginalCar))]
public partial CarChanges ToChanges(Car car);
}

Ignore properties / fields

To ignore a property or field, the MapperIgnoreTargetAttribute or MapperIgnoreSourceAttribute can be used.

[Mapper]
public partial class CarMapper
{
[MapperIgnoreTarget(nameof(CarDto.MakeId))]
[MapperIgnoreSource(nameof(Car.Id))]
public partial CarDto ToDto(Car car);
}

Ignore a member at definition

To ignore a property or field at definition, the MapperIgnoreAttribute can be used.

public partial class CarMapper
{
public partial CarDto ToDto(Car car);
}

public class Car
{
[MapperIgnore]
public int Id { get; set; }

public string ModelName { get; set; }
}

public class CarDto
{
public string ModelName { get; set; }
}

If you want to use the MapperIgnoreAttribute in another .NET Project than the Mapper itself, that project needs to preserve the Mapperly attributes at runtime, see preserving Mapperly attributes at runtime. Without this, the MapperIgnoreAttribute is not visible to Mapperly.

Ignore obsolete members

By default, Mapperly will map source/target members marked with ObsoleteAttribute. This can be changed by setting the IgnoreObsoleteMembersStrategy of a method with MapperIgnoreObsoleteMembersAttribute, or by setting the IgnoreObsoleteMembersStrategy option of the MapperAttribute.

NameDescription
NoneWill map members marked with the Obsolete attribute (default)
BothIgnores source and target members with the Obsolete attribute
SourceIgnores source members with the Obsolete attribute
TargetIgnores target members with the Obsolete attribute

Sets the IgnoreObsoleteMembersStrategy for all methods within the mapper, by default it is None allowing obsolete source and target members to be mapped. This can be overriden by individual mapping methods using MapperIgnoreObsoleteMembersAttribute.

[Mapper(IgnoreObsoleteMembersStrategy = IgnoreObsoleteMembersStrategy.Both)]
public partial class CarMapper
{
...
}

Property name mapping strategy

By default, property and field names are matched using a case sensitive strategy. If all properties/fields differ only in casing, for example ModelName on the source and modelName on the target, the MapperAttribute can be used with the PropertyNameMappingStrategy option.

[Mapper(PropertyNameMappingStrategy = PropertyNameMappingStrategy.CaseInsensitive)]
public partial class CarMapper
{
public partial CarDto ToDto(Car car);
}

public class Car
{
public string ModelName { get; set; }
}

public class CarDto
{
public string modelName { get; set; }
}

null values

Mapperly allows the customization of how null values are handled when mapping properties.

AllowNullPropertyAssignment allows to configure whether null values are assigned to nullable target properties. If it is true and the source value is null, the target property is explicitly set to null. If it is false, the property mapping is ignored or an exception is thrown, depending on the value of ThrowOnPropertyMappingNullMismatch. AllowNullPropertyAssignment is true by default.

ThrowOnPropertyMappingNullMismatch controls how null source values are handled, if the target property is not nullable or AllowNullPropertyAssignment is set to false. If ThrowOnPropertyMappingNullMismatch is enabled, an ArgumentNullException is thrown. If ThrowOnPropertyMappingNullMismatch is disabled, the property mapping is ignored. ThrowOnPropertyMappingNullMismatch is false by default.

For mapping methods the behaviour can be specified via ThrowOnMappingNullMismatch. When the mapper tries to return a null value from a mapping method with a non-nullable return type, and ThrowOnMappingNullMismatch is set to false, Mapperly tries to return a default value. For strings the default value is the empty string, for value types, it is default, for reference types with a public parameterless constructor, a new instance is created. If no such constructor exists an ArgumentNullException is thrown. If ThrowOnMappingNullMismatch is true (default), an ArgumentNullException is thrown.

info

AllowNullPropertyAssignment, ThrowOnPropertyMappingNullMismatch and ThrowOnMappingNullMismatch are ignored for required init properties and IQueryable<T> projection mappings.

One side strict property mappings

By default Mapperly emits diagnostics with a severity of warning if there are unmapped source or target members. To enforce strict mappings on only either the source or the target, the RequiredMappingStrategy can be used.

Sets the RequiredMappingStrategy for all methods within the mapper, by default it is Both requiring all members to be mapped. This can be overriden by individual mapping methods using MapperRequiredMappingAttribute.

[Mapper(RequiredMappingStrategy = RequiredMappingStrategy.Source)]
public partial class CarMapper
{
...
}

String format

The string format passed to ToString calls when converting to a string can be customized by using the StringFormat property of the MapPropertyAttribute.

[Mapper]
public partial class CarMapper
{
[MapProperty(nameof(Car.Price), nameof(CarDto.Price), StringFormat = "C")]
public partial CarDto MapCar(Car car);
}

String format provider & culture

To customize the format provider / culture to be used by Mapperly when calling ToString format providers can be used. A format provider can be provided to Mapperly by simply annotating a field or property within the Mapper with the FormatProviderAttribute. The field/property need to return a type implementing System.IFormatProvider. Format providers can be referenced by the name of the property / field in MapPropertyAttribute.FormatProvider. A format provider can be marked as default (set the default property of the FormatProviderAttribute to true). A default format provider is used for all ToString conversions when the source implements has a ToString overload accepting a System.IFormatProvider. In a mapper only one format provider can be marked as default.

[Mapper]
public partial class CarMapper
{
[FormatProvider(Default = true)]
private IFormatProvider CurrentCulture => CultureInfo.CurrentCulture;

[FormatProvider]
private readonly IFormatProvider _enCulture = CultureInfo.GetCultureInfo("en-US");

[MapProperty(nameof(Car.LocalPrice), nameof(CarDto.LocalPrice), StringFormat = "C")]
[MapProperty(nameof(Car.ListPrice), nameof(CarDto.ListPrice), StringFormat = "C", FormatProvider = nameof(_enCulture)]
public partial CarDto MapCar(Car car);

// generates
target.LocalPrice = source.LocalPrice.ToString("C", CurrentCulture);
target.ListPrice = source.ListPrice.ToString("C", _enCulture);
}

User-implemented property mappings

To use a custom implemented mapping for a specific property or field, the Use property of the MapProperty attribute can be used. Set it to a unique name of a user-implemented mapping method. The use of nameof is encouraged. See also user-implemented mapping methods.

[Mapper]
public partial class CarMapper
{
[MapProperty(nameof(Car.Price), nameof(CarDto.Price), Use = nameof(MapPrice))]
public partial CarDto MapCar(Car source);

// set Default = false to not use it for all decimal => string conversions
// if using AutoUserMappings = false, the UserMapping is not needed.
[UserMapping(Default = false)]
private string MapPrice(decimal price)
=> (price / 100).ToString("C");

// generates
target.Price = MapPrice(source.Price);
}

User-implemented mapping from source

The Use property can also be assigned on the MapPropertyFromSource attribute, for example to access multiple properties of the source in the mapping method:

[Mapper]
public partial class CarMapper
{
[MapPropertyFromSource(nameof(CarDto.NetPrice), Use = nameof(MapPrice))]
public partial CarDto MapCar(Car source);

private decimal MapPrice(Car car)
=> car.Price - car.Discount;

// generates
target.NetPrice = MapPrice(source);
}