MintPlayer.Mapper
13.0.0
dotnet add package MintPlayer.Mapper --version 13.0.0
NuGet\Install-Package MintPlayer.Mapper -Version 13.0.0
<PackageReference Include="MintPlayer.Mapper" Version="13.0.0"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference>
<PackageVersion Include="MintPlayer.Mapper" Version="13.0.0" />
<PackageReference Include="MintPlayer.Mapper"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference>
paket add MintPlayer.Mapper --version 13.0.0
#r "nuget: MintPlayer.Mapper, 13.0.0"
#:package MintPlayer.Mapper@13.0.0
#addin nuget:?package=MintPlayer.Mapper&version=13.0.0
#tool nuget:?package=MintPlayer.Mapper&version=13.0.0
Mapper-generator
This library contains source-generators that automatically generates mapper extension-methods for you.
Getting started
You need to install both MintPlayer.Mapper and MintPlayer.Mapper.Attributes packages in your project:
dotnet add package MintPlayer.Mapper
dotnet add package MintPlayer.Mapper.Attributes
The generator is a development dependency, so dotnet add package and the Visual Studio package manager reference it
with PrivateAssets="all" and an IncludeAssets list without compile. That list applies to the generator's own
dependencies too: the attributes package is restored but not compiled against, and [GenerateMapper] is CS0246 until
you reference the attributes package yourself.
Basic mapping
This demo shows how you can:
- Rename properties
- Change data-types
- Use the generated extension methods
You can mark a class with [GenerateMapper(typeof(TargetType))] to generate a mapper to another type.
[GenerateMapper(typeof(PersonDto))]
public class Person
{
[MapTo(nameof(PersonDto.Naam))]
public string Name { get; set; }
[MapTo(nameof(PersonDto.HoofdAdres))]
public Address MainAddress { get; set; }
[MapTo(nameof(PersonDto.ContactGegevens))]
public ContactInfo[] ContactInfos { get; set; }
[MapTo(nameof(PersonDto.Gewicht))]
public double Weight { get; set; }
// Property with a state (plaintext, base64, ...)
[MapperState<EKeyType>(EKeyType.Plain)]
public string Key { get; set; }
}
public enum EKeyType
{
Plain,
Base64
}
public class PersonDto
{
public string Naam { get; set; }
public AddressDto HoofdAdres { get; set; }
public ContactInfoDto[] ContactGegevens { get; set; }
public string Gewicht { get; set; }
// Property with a state (plaintext, base64, ...)
[MapperState<EKeyType>(EKeyType.Base64)]
public string Key { get; set; }
}
public static class Conversions
{
[MapperConversion]
public static double StringToDouble(string input)
{
if (double.TryParse(input, out double result))
return result;
return 0;
}
[MapperConversion]
public static string DoubleToString(double input)
{
return input.ToString();
}
// Conversion inbetween states, same property types
[MapperConversion<EKeyType>(EKeyType.Plain, EKeyType.Base64)]
public static string StringToBase64(string input)
{
var bytes = System.Text.Encoding.UTF8.GetBytes(input);
return Convert.ToBase64String(bytes);
}
[MapperConversion<EKeyType>(EKeyType.Base64, EKeyType.Plain)]
public static string Base64ToString(string input)
{
var bytes = Convert.FromBase64String(input);
return System.Text.Encoding.UTF8.GetString(bytes);
}
}
Usage
var person = new Person {
Name = "John Doe",
MainAddress = new Address {
Street = "123 Main St",
City = "Anytown"
},
ContactInfos = [
new ContactInfo { Type = "Email", Value = "info@example.com" },
new ContactInfo { Type = "Phone", Value = "123-456-7890" }
],
Weight = 70.5,
Key = "Abc123!",
};
var dto = person.MapToPersonDto();
var entity = dto.MapToPerson();
Debugger.Break();
Example
A more complete example is available here.
Assembly-Level Usage
If you cannot apply [GenerateMapper] directly on a type (e.g. third-party classes), you can also apply it on the assembly:
[assembly: GenerateMapper(typeof(SourceType), typeof(TargetType))]
This will generate a mapper between the given types at the assembly level.
A third argument sets the method-name prefix: [assembly: GenerateMapper(typeof(Person), typeof(PersonDto), "Convert")]
generates ConvertPersonDto() and ConvertPerson(). A property of a mapped type inside another mapped type calls
that same method.
Diagnostics
| Rule ID | Severity | Description |
|---|---|---|
| MAPC001 | Error | Assembly-level [GenerateMapper] must have two types |
| MAPC002 | Error | Type-level [GenerateMapper] must have one type |
| MAPC005 | Error | A mapped type cannot be instantiated (interface, abstract, static, ref struct, open generic) |
| MAPC006 | Error | A mapped type is not accessible from the generated mapper (private, protected or file-local) |
| MAPC007 | Error | A [MapperConversion] method cannot be called from the generated mapper (generic, or in an inaccessible class) |
Mapping to and from structs and record structs works too. For a value-type destination there is no copy overload
MapToX(input, output): it would write into a copy.
Property States
In some cases, two properties may share the same type (e.g. both are string) but represent different formats.
Normally, these properties would be assigned directly without passing through a conversion.
You can explicitly mark such properties with a [MapperState<TEnum>(state)] attribute.
This ensures that the mapping will still go through the ConvertProperty<> method and apply the appropriate MapperConversion.
public enum EKeyType
{
Plain,
Base64
}
public class PlainKeyDto
{
[MapperState<EKeyType>(EKeyType.Plain)]
public string Key { get; set; }
}
public class Base64KeyDto
{
[MapperState<EKeyType>(EKeyType.Base64)]
public string Key { get; set; }
}
public static class Conversions
{
[MapperConversion<EKeyType>(EKeyType.Plain, EKeyType.Base64)]
public static string ToBase64(string plain, EKeyType inType, EKeyType outType)
=> Convert.ToBase64String(Encoding.UTF8.GetBytes(plain));
[MapperConversion<EKeyType>(EKeyType.Base64, EKeyType.Plain)]
public static string FromBase64(string base64, EKeyType inType, EKeyType outType)
=> Encoding.UTF8.GetString(Convert.FromBase64String(base64));
}
In this example:
- Both properties are
string - Without
[MapperState], the mapper would assignKeydirectly - With
[MapperState], the mapper forces a conversion:plain → base64callsToBase64base64 → plaincallsFromBase64
This makes it possible to handle format-specific conversions even when the property types are identical.
Complete example
using MintPlayer.Mapper.Attributes;
using System.Diagnostics;
using MapperDemo;
var person = new Person
{
Name = "John Doe",
MainAddress = new Address
{
Street = "123 Main St",
City = "Anytown",
Country = "USA",
Number = "A1",
PostalCode = "12345",
},
ContactInfos = [
new ContactInfo { Type = "Email", Value = "info@example.com" },
new ContactInfo { Type = "Phone", Value = "123-456-7890" }
],
Notes = ["Note 1", "Note 2"],
Weight = 70.5,
Key = "QWJjMTIzIQ==",
};
var dto = person.MapToPersonDto();
var entity = dto.MapToPerson();
Debugger.Break();
namespace MapperDemo
{
[GenerateMapper(typeof(PersonDto))]
public class Person
{
[MapTo(nameof(PersonDto.Naam))]
public string Name { get; set; }
[MapTo(nameof(PersonDto.HoofdAdres))]
public Address MainAddress { get; set; }
[MapTo(nameof(PersonDto.Notities))]
public string[] Notes { get; set; }
[MapTo(nameof(PersonDto.ContactGegevens))]
public ContactInfo[] ContactInfos { get; set; }
[MapTo(nameof(PersonDto.Gewicht))]
public double Weight { get; set; }
// Property with a state (plaintext, base64, ...)
[MapperState<EKeyType>(EKeyType.Plain)]
public string Key { get; set; }
}
[GenerateMapper(typeof(AddressDto))]
public class Address
{
[MapTo(nameof(AddressDto.Straat))]
public string Street { get; set; }
[MapTo(nameof(AddressDto.Nummer))]
public string Number { get; set; }
[MapTo(nameof(AddressDto.Gemeente))]
public string City { get; set; }
[MapTo(nameof(AddressDto.Postcode))]
public string PostalCode { get; set; }
[MapTo(nameof(AddressDto.Land))]
public string Country { get; set; }
}
[GenerateMapper(typeof(ContactInfoDto))]
public class ContactInfo
{
[MapTo(nameof(ContactInfoDto.Type))]
public string Type { get; set; }
[MapTo(nameof(ContactInfoDto.Waarde))]
public string Value { get; set; }
}
public class PersonDto
{
public string Naam { get; set; }
public AddressDto HoofdAdres { get; set; }
public string[] Notities { get; set; }
public ContactInfoDto[] ContactGegevens { get; set; }
public string Gewicht { get; set; }
// Property with a state (plaintext, base64, ...)
[MapperState<EKeyType>(EKeyType.Base64)]
public string Key { get; set; }
}
public class AddressDto
{
public string Straat { get; set; }
public string Nummer { get; set; }
public string Gemeente { get; set; }
public string Postcode { get; set; }
public string Land { get; set; }
}
public class ContactInfoDto
{
public string Type { get; set; }
public string Waarde { get; set; }
}
public enum EKeyType
{
Plain,
Base64
}
public static class Conversions
{
[MapperConversion]
public static double StringToDouble(string input)
{
if (double.TryParse(input, out double result))
return result;
return 0;
}
[MapperConversion]
public static string DoubleToString(double input)
{
return input.ToString();
}
// Conversion inbetween states, same property types
[MapperConversion<EKeyType>(EKeyType.Plain, EKeyType.Base64)]
public static string StringToBase64(string input)
{
var bytes = System.Text.Encoding.UTF8.GetBytes(input);
return Convert.ToBase64String(bytes);
}
[MapperConversion<EKeyType>(EKeyType.Base64, EKeyType.Plain)]
public static string Base64ToString(string input)
{
var bytes = Convert.FromBase64String(input);
return System.Text.Encoding.UTF8.GetString(bytes);
}
}
}
Learn more about Target Frameworks and .NET Standard.
-
.NETStandard 2.0
- MintPlayer.Mapper.Attributes (>= 13.0.0)
- MintPlayer.ValueComparerGenerator.Attributes (>= 13.0.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated | |
|---|---|---|---|
| 13.0.0 | 0 | 10/11/2026 | |
| 12.2.0 | 34 | 10/11/2026 | |
| 12.1.1 | 100 | 10/2/2026 | |
| 12.1.0 | 103 | 9/26/2026 | |
| 12.0.1 | 119 | 9/25/2026 | |
| 12.0.0 | 109 | 9/25/2026 | |
| 11.0.0 | 113 | 9/25/2026 | |
| 10.21.1 | 128 | 9/3/2026 | |
| 10.21.0 | 120 | 8/27/2026 | |
| 10.20.1 | 110 | 8/27/2026 | |
| 10.20.0 | 137 | 6/5/2026 | |
| 10.19.0 | 136 | 4/3/2026 | |
| 10.14.0 | 154 | 2/8/2026 | |
| 10.13.0 | 140 | 1/19/2026 | |
| 10.10.1 | 143 | 1/12/2026 | |
| 10.10.0 | 149 | 1/12/2026 | |
| 10.9.0 | 158 | 1/12/2026 | |
| 10.8.0 | 227 | 12/24/2025 | |
| 10.7.0 | 329 | 11/13/2025 | |
| 10.5.0 | 344 | 11/11/2025 |