Mappa.Generator
1.0.0
dotnet add package Mappa.Generator --version 1.0.0
NuGet\Install-Package Mappa.Generator -Version 1.0.0
<PackageReference Include="Mappa.Generator" Version="1.0.0"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference>
<PackageVersion Include="Mappa.Generator" Version="1.0.0" />
<PackageReference Include="Mappa.Generator"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference>
paket add Mappa.Generator --version 1.0.0
#r "nuget: Mappa.Generator, 1.0.0"
#addin nuget:?package=Mappa.Generator&version=1.0.0
#tool nuget:?package=Mappa.Generator&version=1.0.0
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):
- <u>Existing method strategy</u>
- When:
- A method in the same class from
TSource
toTTarget
exists OR, - A method from a property or field marked with the
[MappaDependency]
fromTSource
toTTarget
exists;
- A method in the same class from
- 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;
- When:
- <u>Identity strategy</u>:
- When:
TSource
andTTarget
are the same type (e.g.TSource => int
andTTarget => int
) OR,TSource
can be implicitly converted intoTTarget
(e.g.TSource => int
andTTarget => long
);
- What:
- the input value is simply assigned to the target;
- When:
- <u>Nullable strategy</u>:
- When:
TSource
is theNullable<T>
value type (e.g.int?
) OR,TSource
is anullable
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 benull
the mapper will return null OR, - if
TTarget
cannot benull
the mapper will throw aNullReferenceException
;
- if
- When:
- <u>
enum
strategy</u>:- When:
TSource
is anenum
andTTarget
is a differentenum
, an integral numeric type compatible with theenum
or a string OR,TSource
is a differentenum
, an integral numeric type compatible with theenum
andTTarget
is anenum
;
- What:
- a
switch
statement is introduced to quickly mapTSource
toTTarget
using all the possible values of theenum
,
- a
- When:
- <u>
string
strategy</u>:- When:
TSource
is astring
andTTarget
is any of the following typesDateTime
,DateTimeOffset
,DateOnly
,TimeOnly
,Guid
,Uri
OR,TTarget
is astring
;
- What:
TSource
is astring
andTTarget
is any of the following typesDateTime
,DateTimeOffset
,DateOnly
,TimeOnly
,Guid
then theirTTarget.Parse
method will be used, possibly with the format and culture identified by theMappaSettings
attribute, if any is provided on the class or on the method;TSource
is astring
andTTarget
isUri
then theSystem.UriBuilder
will be used for the mappingTTarget
is astring
andTSource
is any of the following typesDateTime
,DateTimeOffset
,DateOnly
,TimeOnly
,Guid
then theirTSource.ToString()
method will be used, possibly with the format and culture identified by theMappaSettings
attribute, if any is provided on the class or on the method;TTarget
is astring
then theTSource.ToString
method will be used
- When:
- <u>Date & Time strategy</u>:
- When:
TSource
is aDateTime
andTTarget
islong
or,DateTime
or,TimeOnly
OR,TSource
is aDateTimeOffset
andTTarget
islong
or,DateTime
or,DateTime
or,TimeOnly
OR,TSource
is aDateOnly
andTTarget
islong
or,DateTime
OR,TSource
is along
andTTarget
isDateTime
or,DateTimeOffset
OR,TSource
is aTimeSpan
andTTarget
isdouble
OR,TSource
is adouble
andTTarget
isTimeSpan
OR,
- What:
- The usual mapping conversions are used;
- When mapping from
DateOnly
toDateTime
orDateTimeOffset
theTimeOnly.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
toDateTimeOffset
is handled by the identify strategy;
- The mapping from
- When:
- <u>Container strategy</u>:
- When:
TSource
andTTarget
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>>
;
- any type implementing
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>
- any type implementing
TSource
collection types accepted: any type implementingIEnumerable<T>
, arrays,Span<T>
,ReadOnlySpan<T>
,Memory<T>
andReadOnlyMemory<T>
;TTarget
collection types accepted:- any type implementing
ICollection<T>
orISet<T>
that has a constructor with zero arguments; - any type derived from
Stack<T>
orQueue<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>
;
- any type implementing
- What:
- A
for
loop orforeach
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;
- A
- 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;
- When possible for some types (e.g.
- When:
- <u>Tuples strategy</u>:
- When:
TSource
andTTarget
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;
- When:
- <u>Constructor strategy</u>:
- When:
TTarget
type has one constructor with no parameters and each property with a setter can be assigned from aTSource
property with the same name (case-sensitive) OR,TTarget
type has one constructor with parameters and each constructor argument can be assigned from aTSource
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;
- Each property or constructor argument is mapped and a new instance of
- Notes:
- Explicit interface implementation is supported for get-only dictionary and collection properties;
- Multiple Mappa attributes can change the behaviour of the mapping;
- When:
Currently unsupported features are:
- Polymorphism;
- Generics;
- Format and culture when mapping numeric types to and from strings;
- Use of
Span<T>
orReadOnly<T>
for fast iterations over collections; ValueType<T>
tuples.
Other relevant packages:
- Mappa: source generator that allows to automatically generate mapping between classes and value types;
- Mappa Protobuf: methods to map
Google.Protobuf.WellKnownTypes
objects from Google.Protobuf package into common objects. - Mappa Protobuf dependency: utility methods to register the Protobuf mapper.
- Mappa Bson: methods to map
MongoDB.Bson
objects from MongoDB.Bson package into common objects. - Mappa Bson dependency: utility methods to register the Bson mapper.
You can find samples here. Visit the Mappa documentation to learn more.
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 |