Mappa.Generator
1.2.0
dotnet add package Mappa.Generator --version 1.2.0
NuGet\Install-Package Mappa.Generator -Version 1.2.0
<PackageReference Include="Mappa.Generator" Version="1.2.0"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference>
<PackageVersion Include="Mappa.Generator" Version="1.2.0" />
<PackageReference Include="Mappa.Generator"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference>
paket add Mappa.Generator --version 1.2.0
#r "nuget: Mappa.Generator, 1.2.0"
#:package Mappa.Generator@1.2.0
#addin nuget:?package=Mappa.Generator&version=1.2.0
#tool nuget:?package=Mappa.Generator&version=1.2.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
TSourcetoTTargetexists OR, - A method from a property or field marked with the
[MappaDependency]fromTSourcetoTTargetexists;
- 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:
TSourceandTTargetare the same type (e.g.TSource => intandTTarget => int) OR,TSourcecan be implicitly converted intoTTarget(e.g.TSource => intandTTarget => long);
- What:
- the input value is simply assigned to the target;
- When:
- <u>Nullable strategy</u>:
- When:
TSourceis theNullable<T>value type (e.g.int?) OR,TSourceis anullablereference type when#nullable enable(e.g.string?) OR,TSourceis a reference type when#nullable disable(e.g.string),- AND a mapping exists from source to target when stripped of the nullablity;
- What:
- if
TTargetcan benullthe mapper will return null OR, - if
TTargetcannot benullthe mapper will throw aNullReferenceException;
- if
- When:
- <u>
enumstrategy</u>:- When:
TSourceis anenumandTTargetis a differentenum, an integral numeric type compatible with theenumor a string OR,TSourceis a differentenum, an integral numeric type compatible with theenumandTTargetis anenum;
- What:
- a
switchstatement is introduced to quickly mapTSourcetoTTargetusing all the possible values of theenum,
- a
- When:
- <u>
stringstrategy</u>:- When:
TSourceis astringandTTargetis any of the following typesDateTime,DateTimeOffset,DateOnly,TimeOnly,Guid,UriOR,TTargetis astring;
- What:
TSourceis astringandTTargetis any of the following typesDateTime,DateTimeOffset,DateOnly,TimeOnly,Guidthen theirTTarget.Parsemethod will be used, possibly with the format and culture identified by theMappaSettingsattribute, if any is provided on the class or on the method;TSourceis astringandTTargetisUrithen theSystem.UriBuilderwill be used for the mappingTTargetis astringandTSourceis any of the following typesDateTime,DateTimeOffset,DateOnly,TimeOnly,Guidthen theirTSource.ToString()method will be used, possibly with the format and culture identified by theMappaSettingsattribute, if any is provided on the class or on the method;TTargetis astringthen theTSource.ToStringmethod will be used
- When:
- <u>Date & Time strategy</u>:
- When:
TSourceis aDateTimeandTTargetislongor,DateTimeor,TimeOnlyOR,TSourceis aDateTimeOffsetandTTargetislongor,DateTimeor,DateTimeor,TimeOnlyOR,TSourceis aDateOnlyandTTargetislongor,DateTimeOR,TSourceis alongandTTargetisDateTimeor,DateTimeOffsetOR,TSourceis aTimeSpanandTTargetisdoubleOR,TSourceis adoubleandTTargetisTimeSpanOR,
- What:
- The usual mapping conversions are used;
- When mapping from
DateOnlytoDateTimeorDateTimeOffsettheTimeOnly.Zerois used; - When mapping to or from
longthe Unix time is used; - When a timezone is required UTC is implied;
- Notes:
- The mapping from
DateTimetoDateTimeOffsetis handled by the identify strategy;
- The mapping from
- When:
- <u>Container strategy</u>:
- When:
TSourceandTTargetare 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 exists from the source element type to the target element type,
TSourcedictionary types accepted:- any type implementing
IDictionary<TKey, TValue>; - any type implementing
IReadOnlyDictionary<TKey, TValue>; - any type implementing
IEnumerable<KeyValuePair<<TKey, TValue>>;
- any type implementing
TTargetdictionary 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>,ConcurrentDictionary<TKey, TValue>;
- any type implementing
TSourcecollection types accepted: any type implementingIEnumerable<T>, arrays,Span<T>,ReadOnlySpan<T>,Memory<T>andReadOnlyMemory<T>;TTargetcollection 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>,IProducerConsumerCollection<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>,BlockingColletion<T>,ConcurrentBag<T>,ConcurrentQueue<T>,ConcurrentStack<T>;
- any type implementing
- What:
- A
forloop orforeachloop 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;
- Type with an empty constructor are supported if they are derived from any of the supported interfaces or classes;
- When possible for some types (e.g.
- When:
- <u>Tuples strategy</u>:
- When:
TSourceandTTargetare 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>Guid strategy</u>:
- When:
TSourceisGuidandTTargetisbyte[]orSpan<byte>orReadOnlySpan<byte>orMemory<byte>orReadOnlyMemory<byte>, ORTSourceisbyte[]orSpan<byte>orReadOnlySpan<byte>orMemory<byte>orReadOnlyMemory<byte>andTTargetisGuid;
- What:
- A mapping from
Guidtobyte[]/Span<byte>is defined using the relevantGuidconstructors or theGuid.ToByteArray()method
- A mapping from
- When:
- <u>Constructor strategy</u>:
- When:
TTargettype has one constructor with no parameters and each property with a setter can be assigned from aTSourceproperty with the same name (case-sensitive) OR,TTargettype has one constructor with parameters and each constructor argument can be assigned from aTSourceproperty with the same name (case-insensitive);
- What:
- Each property or constructor argument is mapped and a new instance of
TTargetis 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.WellKnownTypesobjects from Google.Protobuf package into common objects. - Mappa Protobuf dependency: utility methods to register the Protobuf mapper.
- Mappa Bson: methods to map
MongoDB.Bsonobjects 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.