Mappa.Generator 1.0.0

dotnet add package Mappa.Generator --version 1.0.0
                    
NuGet\Install-Package Mappa.Generator -Version 1.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="Mappa.Generator" Version="1.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="Mappa.Generator" Version="1.0.0" />
                    
Directory.Packages.props
<PackageReference Include="Mappa.Generator">
  <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 Mappa.Generator --version 1.0.0
                    
#r "nuget: Mappa.Generator, 1.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.
#addin nuget:?package=Mappa.Generator&version=1.0.0
                    
Install Mappa.Generator as a Cake Addin
#tool nuget:?package=Mappa.Generator&version=1.0.0
                    
Install Mappa.Generator as a Cake Tool

Mappa.Generator

This source generator generates code for partial methods in partial classes tagged with the [Mappa] attribute defined in the Mappa package. The generated code allow to map from a source type to a target type.

Assuming you have a partial method like the following

[Mappa]
public partial class Mapper
{
    public partial TTarget Map(TSource input);
}

where TSource is the source type of the mapping and TTarget is the target type of the mapping, the source generator works by applying the following set of strategies in the order they are defined (see TypeMapIdentifierAlgorithm.cs):

  1. <u>Existing method strategy</u>
    • When:
      • A method in the same class from TSource to TTarget exists OR,
      • A method from a property or field marked with the [MappaDependency] from TSource to TTarget exists;
    • What:
      • the method is invoked;
    • Notes:
      • This strategy is usually used when mapping element of an array, keys or values of dictionaries, elements of tuples, properties of class/struct/record;
  2. <u>Identity strategy</u>:
    • When:
      • TSource and TTarget are the same type (e.g. TSource => int and TTarget => int) OR,
      • TSource can be implicitly converted into TTarget (e.g. TSource => int and TTarget => long);
    • What:
      • the input value is simply assigned to the target;
  3. <u>Nullable strategy</u>:
    • When:
      • TSource is the Nullable<T> value type (e.g. int?) OR,
      • TSource is a nullable reference type when #nullable enable (e.g. string?) OR,
      • TSource is a reference type when #nullable disable (e.g. string),
      • AND a mapping exists from source to target when stripped of the nullablity;
    • What:
      • if TTarget can be null the mapper will return null OR,
      • if TTarget cannot be null the mapper will throw a NullReferenceException;
  4. <u>enum strategy</u>:
    • When:
      • TSource is an enum and TTarget is a different enum, an integral numeric type compatible with the enum or a string OR,
      • TSource is a different enum, an integral numeric type compatible with the enum and TTarget is an enum;
    • What:
      • a switch statement is introduced to quickly map TSource to TTarget using all the possible values of the enum,
  5. <u>string strategy</u>:
    • When:
      • TSource is a string and TTarget is any of the following types DateTime, DateTimeOffset, DateOnly, TimeOnly, Guid, Uri OR,
      • TTarget is a string;
    • What:
      • TSource is a string and TTarget is any of the following types DateTime, DateTimeOffset, DateOnly, TimeOnly, Guid then their TTarget.Parse method will be used, possibly with the format and culture identified by the MappaSettings attribute, if any is provided on the class or on the method;
      • TSource is a string and TTarget is Uri then the System.UriBuilder will be used for the mapping
      • TTarget is a string and TSource is any of the following types DateTime, DateTimeOffset, DateOnly, TimeOnly, Guid then their TSource.ToString() method will be used, possibly with the format and culture identified by the MappaSettings attribute, if any is provided on the class or on the method;
      • TTarget is a string then the TSource.ToString method will be used
  6. <u>Date & Time strategy</u>:
    • When:
      • TSource is a DateTime and TTarget is long or,DateTime or, TimeOnly OR,
      • TSource is a DateTimeOffset and TTarget is long or, DateTime or, DateTime or, TimeOnly OR,
      • TSource is a DateOnly and TTarget is long or, DateTime OR,
      • TSource is a long and TTarget is DateTime or, DateTimeOffset OR,
      • TSource is a TimeSpan and TTarget is double OR,
      • TSource is a double and TTarget is TimeSpan OR,
    • What:
      • The usual mapping conversions are used;
      • When mapping from DateOnly to DateTime or DateTimeOffset the TimeOnly.Zero is used;
      • When mapping to or from long the Unix time is used;
      • When a timezone is required UTC is implied;
    • Notes:
      • The mapping from DateTime to DateTimeOffset is handled by the identify strategy;
  7. <u>Container strategy</u>:
    • When:
      • TSource and TTarget are both either dictionaries or collections,
      • For dictionaries mappings exist from source key type to the target key type and from the source value type to the target value type,
      • For collections a mapping exist from source element type to the target element type,
      • TSource dictionary types accepted:
        • any type implementing IDictionary<TKey, TValue>;
        • any type implementing IReadOnlyDictionary<TKey, TValue>;
        • any type implementing IEnumerable<KeyValuePair<<TKey, TValue>>;
      • TTarget dictionary types accepted:
        • any type implementing IDictionary<TKey, TValue> that has a constructor with zero arguments;
        • the following interfaces: IDictionary<TKey, TValue>, IReadOnlyDictionary<TKey, TValue>, IImmutableDictionary<TKey, TValue>;
        • the following classes: ImmutableDictionary<TKey, TValue>, ImmutableSortedDictionary<TKey, TValue>, FrozenDictionary<TKey, TValue>
      • TSource collection types accepted: any type implementing IEnumerable<T>, arrays, Span<T>, ReadOnlySpan<T>, Memory<T> and ReadOnlyMemory<T>;
      • TTarget collection types accepted:
        • any type implementing ICollection<T> or ISet<T> that has a constructor with zero arguments;
        • any type derived from Stack<T> or Queue<T> that has a constructor with zero arguments;
        • the following interfaces: IEnumerable<T>, ICollection<T>, IReadOnlyCollection<T>, ISet<T>, IList<T>, IReadOnlyList<T>, IReadOnlySet<T>, IImmutableSet<T>, IImmutableList<T>, IImmutableQueue<T>, IImmutableStack<T>;
        • the following classes: arrays, List<T>, ReadOnlyCollection<T>, Span<T>, ReadOnlySpan<T>, Memory<T>, ReadOnlyMemory<T>, Stack<T>, Queue<T>, ReadOnlySet<T>, HashSet<T>, SortedSet<T>, ReadOnlyColletion<T>, FrozenSet<T>, ImmutableHashSet<T>, ImmutableSortedSet<T>, ImmutableArray<T>, ImmutableList<T>, ImmutableQueue<T>, ImmutableStack<T>;
    • What:
      • A for loop or foreach loop is added to the code;
      • In the loop each element from the source collection is mapped in an element of the target collection and then added to the target collection;
    • Notes:
      • When possible for some types (e.g. List<T>) the usage of the constructor accepting capacity is preferred to reduce the number of allocations;
      • Explicit interface implementation is supported;
  8. <u>Tuples strategy</u>:
    • When:
      • TSource and TTarget are both tuple types,
      • The number of the elements in the tuple is the same,
      • For each element of the tuple there exists a mapping from source element to target element;
    • What:
      • Each element of the source tuple is mapped into a new element of the target tuple;
      • The target tuple is created by combining the elements mapped;
    • Notes:
      • Both named and un-named tuples are supported
      • The type Tuple<T> (and its variations with more elements) are supported;
  9. <u>Constructor strategy</u>:
    • When:
      • TTarget type has one constructor with no parameters and each property with a setter can be assigned from a TSource property with the same name (case-sensitive) OR,
      • TTarget type has one constructor with parameters and each constructor argument can be assigned from a TSource property with the same name (case-insensitive);
    • What:
      • Each property or constructor argument is mapped and a new instance of TTarget is generated;
      • Get-only dictionary or collection properties for which a mapper exists are filled with mapped values from the corresponding source;
    • Notes:
      • Explicit interface implementation is supported for get-only dictionary and collection properties;
      • Multiple Mappa attributes can change the behaviour of the mapping;

Currently unsupported features are:

  • Polymorphism;
  • Generics;
  • Format and culture when mapping numeric types to and from strings;
  • Use of Span<T> or ReadOnly<T> for fast iterations over collections;
  • ValueType<T> tuples.

Other relevant packages:

You can find samples here. Visit the Mappa documentation to learn more.

There are no supported framework assets in this package.

Learn more about Target Frameworks and .NET Standard.

  • .NETStandard 2.0

    • No dependencies.

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
1.0.0 77 3/29/2025