laget.Mapper 1.3.27

Prefix Reserved
dotnet add package laget.Mapper --version 1.3.27                
NuGet\Install-Package laget.Mapper -Version 1.3.27                
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="laget.Mapper" Version="1.3.27" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add laget.Mapper --version 1.3.27                
#r "nuget: laget.Mapper, 1.3.27"                
#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.
// Install laget.Mapper as a Cake Addin
#addin nuget:?package=laget.Mapper&version=1.3.27

// Install laget.Mapper as a Cake Tool
#tool nuget:?package=laget.Mapper&version=1.3.27                

laget.Mapper

An extremely simple object-object mapper.

Nuget Nuget

Configuration

This example is shown using Autofac since this is the go-to IoC for us.

await Host.CreateDefaultBuilder()
    .ConfigureContainer<ContainerBuilder>((context, builder) =>
    {
        builder.RegisterMappers();
    })
    .UseServiceProviderFactory(new AutofacServiceProviderFactory())
    .Build()
    .RunAsync();

This is the simplest way to register your mappers but also has some constraints:

  • The mapper implementations must exist in the program that calls RegisterMappers.
  • The mapper implementations must implement the interface IMapper.
await Host.CreateDefaultBuilder()
    .ConfigureContainer<ContainerBuilder>((context, builder) =>
    {
        builder.RegisterMappers(_ =>
        {
            _.TheCallingAssembly();
            _.TheCallingAssembly<T>();
            _.AssemblyContainingType<T>();
            _.Assembly("Mappers");
        });
    })
    .UseServiceProviderFactory(new AutofacServiceProviderFactory())
    .Build()
    .RunAsync();

This is the advanced and more customizable way to register your mappers

  • TheCallingAssembly(); will register mapper implementations from the calling assembly that implements the interface IMapper.
  • TheCallingAssembly<T>(); will register mapper implementations from the calling assembly that implements the interface T.
  • AssemblyContainingType<T>(); will register mapper implementations from the assembly of the provided type, this is useful if you e.g. have class libraries with Mappers and/or custom implementations of IMapper.
  • Assembly("name"); will register mapper implementations in the assembly, will load assembly via the name provided using System.Reflection, that implements the interface IMapper.

Usage

Creating a mapper class

To create a mapper class use the marker interface IMapper to mark the class and the MapperMethod attribute to mark all methods in the class that are mapping methods.

The global mapper will pick up all classes tagged with the IMapper marker interface and register all methods tagged with the MapperMethod that match the following critera

  • The method is not private
  • The method has a non void return value
  • The method has only one parameter
public class ModelMapper : IMapper 
{
    [MapperMethod] // Will be registered as the mapping method for converting Model -> Entity
    public Entity ModelToEntity(Model model) => 
        new Entity 
        {
            // ...
        };
        
    [MapperMethod] // Will be registered as the mapping method for converting Dto -> Model
    public Model ModelFromDto(Dto dto) => 
        new Model 
        {
            // ...
        };
        
    [MapperMethod] // Will not be registered as the mapping method for converting Dto -> Model is already defined above
    public Model ModelFromDto2(Dto dto) => 
        new Model 
        {
            // ...
        };
        
    // Will not be registered as it lacks the MapperMethod attribute
    public Dto DtoFromModel(Model model) =>
        new Dto 
        {
            // ...
        };
    
    [MapperMethod] // Will not be registered as it is a private method
    private Model ModelFromEntity(Entity entity) =>
        new Model 
        {
            // ...
        };
        
    [MapperMethod] // Will not be registered as it returns void
    public void UpdateModelState(Model model) { /* ... */ }
     
    [MapperMethod] // Will not be registered as it doesn't take a parameter
    public int GetConstantInt() => 42;
        
    [MapperMethod] // Will not be registered as it takes multiple arguments
    public Model ModelFromEntityAndDto(Entity entity, Dto dto) =>
        new Model 
        {
            // ...
        };
}

Using the mapper

The mapper can be used in different ways, either through direct access to the static method

var model = new Model();
var dto = Mapper.Mapper.Map<Dto>(model);
var baseClassDto = Mapper.Mapper.Map<ModelBase, DtoBase>(model);

Or using one of the built in extensions on object or IEnumerable<TSource>

var model = new Model();
var dto = model.Map<Dto>();

var dtos = new [] { new Dto() /*, ... */ };
var models = dtos.Map<Model>();

Using the extensions is the recommended way as it provides a clean way of writing Linq chains, however it can be useful to access the mapper directly if you need to map based on an inherited class.

Benchmarks

BenchmarkDotNet v0.13.12, Windows 10 (10.0.19045.4123/22H2/2022Update) (VMware)
AMD Ryzen Threadripper 3960X, 1 CPU, 12 logical and 12 physical cores
.NET SDK 8.0.200
  [Host]     : .NET 6.0.27 (6.0.2724.6912), X64 RyuJIT AVX2
  Job-BJZLVN : .NET 6.0.27 (6.0.2724.6912), X64 RyuJIT AVX2
  Job-OQIHXW : .NET 8.0.2 (8.0.224.6711), X64 RyuJIT AVX2

IterationCount=10  LaunchCount=1  RunStrategy=Throughput  WarmupCount=5

Mappings

Method Runtime Mean Error StdDev Min Max Median Ratio RatioSD Gen0 Allocated Alloc Ratio
Simple_Mapper .NET 6.0 169.49 ns 3.408 ns 2.254 ns 166.39 ns 172.78 ns 168.89 ns 1.00 0.00 0.0172 144 B 1.00
Simple_Mapper .NET 8.0 63.00 ns 4.291 ns 2.838 ns 59.19 ns 67.89 ns 62.52 ns 0.37 0.02 0.0172 144 B 1.00
DeepType_Mapper .NET 6.0 976.40 ns 9.541 ns 5.678 ns 971.22 ns 986.86 ns 975.08 ns 1.00 0.00 0.1411 1184 B 1.00
DeepType_Mapper .NET 8.0 461.82 ns 27.469 ns 18.169 ns 433.24 ns 488.14 ns 466.44 ns 0.48 0.02 0.1411 1184 B 1.00

Registration

Method Mean Error StdDev Min Max Median Gen0 Allocated
Single_Registration 47.44 ns 5.158 ns 15.127 ns 46.44 ns 21.13 ns 1,989.74 ns 0.0839 720 B
Multiple_Registration 72.98 ns 13.068 ns 38.532 ns 75.02 ns 85.02 ns 4,160.33 ns 0.1831 1568 B
Assembly_Registration 52.25 ns 2.468 ns 7.160 ns 52.30 ns 36.57 ns 1,076.43 ns 0.0515 432 B
AssemblyContainingType_Registration 47.87 ns 1.102 ns 3.248 ns 47.74 ns 43.13 ns 53.77 ns 0.0334 280 B
TheCallingAssembly_Registration 54.38 ns 0.764 ns 2.254 ns 53.33 ns 50.01 ns 57.88 ns 0.0334 280 B
TheCallingAssemblyT_Registration 54.31 ns 1.045 ns 3.082 ns 54.44 ns 48.48 ns 59.92 ns 0.0334 280 B
TheEntryAssembly_Registration 50.83 ns 1.015 ns 2.993 ns 49.76 ns 47.22 ns 59.54 ns 0.0334 280 B
TheEntryAssemblyT_Registration 49.96 ns 0.665 ns 1.961 ns 48.95 ns 47.30 ns 52.91 ns 0.0334 280 B
TheExecutingAssembly_Registration 657.93 ns 1.320 ns 3.831 ns 657.71 ns 649.10 ns 667.97 ns 0.0334 280 B
TheExecutingAssemblyT_Registration 699.09 ns 2.773 ns 8.089 ns 699.08 ns 684.46 ns 717.44 ns 0.0334 280 B
Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 is compatible. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in 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
1.3.27 100 9/3/2024
1.3.26 175 3/19/2024
1.2.25 127 3/15/2024
1.2.24 139 3/11/2024
1.2.23 327 1/20/2024
1.2.22 227 11/23/2023
1.2.21 130 11/22/2023
1.2.20 175 9/27/2023
1.1.15 159 7/3/2023
1.1.12 261 3/13/2023
1.1.10 232 3/10/2023
1.0.8 244 3/7/2023