MintPlayer.Mapper 13.0.0

dotnet add package MintPlayer.Mapper --version 13.0.0
                    
NuGet\Install-Package MintPlayer.Mapper -Version 13.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="MintPlayer.Mapper" Version="13.0.0">
  <PrivateAssets>all</PrivateAssets>
  <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="MintPlayer.Mapper" Version="13.0.0" />
                    
Directory.Packages.props
<PackageReference Include="MintPlayer.Mapper">
  <PrivateAssets>all</PrivateAssets>
  <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add MintPlayer.Mapper --version 13.0.0
                    
#r "nuget: MintPlayer.Mapper, 13.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package MintPlayer.Mapper@13.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=MintPlayer.Mapper&version=13.0.0
                    
Install as a Cake Addin
#tool nuget:?package=MintPlayer.Mapper&version=13.0.0
                    
Install as a Cake Tool

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 assign Key directly
  • With [MapperState], the mapper forces a conversion:
    • plain → base64 calls ToBase64
    • base64 → plain calls FromBase64

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);
        }
    }
}
There are no supported framework assets in this package.

Learn more about Target Frameworks and .NET Standard.

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.1 is deprecated.
12.0.0 109 9/25/2026 12.0.0 is deprecated.
11.0.0 113 9/25/2026 11.0.0 is deprecated.
10.21.1 128 9/3/2026 10.21.1 is deprecated.
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
Loading failed