eQuantic.Mapper 1.3.1

There is a newer version of this package available.
See the version list below for details.
dotnet add package eQuantic.Mapper --version 1.3.1                
NuGet\Install-Package eQuantic.Mapper -Version 1.3.1                
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="eQuantic.Mapper" Version="1.3.1" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add eQuantic.Mapper --version 1.3.1                
#r "nuget: eQuantic.Mapper, 1.3.1"                
#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 eQuantic.Mapper as a Cake Addin
#addin nuget:?package=eQuantic.Mapper&version=1.3.1

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

eQuantic.Mapper Library

The eQuantic Mapper provides all the implementation needed to use the Mapper Pattern

To install eQuantic.Mapper, run the following command in the Package Manager Console

Install-Package eQuantic.Mapper

If you choose to use generated mappers, install the Generator package below

Install-Package eQuantic.Mapper.Generator

Example of implementation

The models

public class ExampleA
{
    public string Id { get; set; } = string.Empty;
    public string Name { get; set; } = string.Empty;
    public string Date { get; set; } = string.Empty;
}

public class ExampleB
{
    public int Id { get; set; }
    public string Name { get; set; } = string.Empty;
    public DateTime Date { get; set; }
    
    [MapFrom(typeof(ExampleA), nameof(ExampleA.Id))]
    public string Code { get; set; } = string.Empty;
}

The mapper

public class ExampleMapper : IMapper<ExampleA, ExampleB>
{
    public ExampleB? Map(ExampleA? source)
    {
        return Map(source, new ExampleB());
    }

    public ExampleB? Map(ExampleA? source, ExampleB? destination)
    {
        if (source == null)
        {
            return null;
        }

        if (destination == null)
        {
            return Map(source);
        }
        
        destination.Id = source.Id;
        destination.Name = source.Name;
        destination.Date = source.Date;
        
        return destination;
    }
}

The mapper with context

public class ExampleContext
{
    public string Code { get; set; }
}
public class ExampleMapper : IMapper<ExampleA, ExampleB, ExampleContext>
{
    public ExampleContext Context { get; set; }
    
    public ExampleB? Map(ExampleA? source)
    {
        return Map(source, new ExampleB());
    }

    public ExampleB? Map(ExampleA? source, ExampleB? destination)
    {
        if (source == null)
        {
            return null;
        }

        if (destination == null)
        {
            return Map(source);
        }
        
        destination.Id = source.Id;
        destination.Name = source.Name;
        destination.Date = source.Date;
        
        if(!string.IsNullOrEmpty(Context.Code))
        {
            destination.Code = Context.Code;
        }
        return destination;
    }
}

Auto-Generated Code

If you want that the mapper to be auto-generated, you need to use the MapperAttribute and partial definition into the class mapper

[Mapper(typeof(ExampleA), typeof(ExampleB))]
public partial class ExampleMapper : IMapper
{
}

or

[Mapper(typeof(ExampleA), typeof(ExampleB))]
public partial class AsyncExampleMapper : IAsyncMapper
{
}

The application

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddMappers();
var app = builder.Build();

app.MapGet("/", (IMapperFactory mapperFactory) =>
{
    var mapper = mapperFactory.GetMapper<ExampleA, ExampleB>()!;
    var exampleA = new ExampleA
    {
        Id = "1",
        Name = "Test",
        Date = "2023-01-01"
    };
    var exampleB = mapper.Map(exampleA);
    return exampleB;
});

app.Run();

Manual customization

If you need customize the auto-generated mapper, just override Before or/and After methods:

[Mapper(typeof(ExampleA), typeof(ExampleB))]
public partial class ExampleMapper : IMapper
{
    partial void AfterMap(ExampleA source, ExampleB destination)
    {
        if(source.Name == "Test")
        {
            destination.Name = "Empty";
        }
    }
}

Debugging

Inside MapperGenerator on Initialize method use:

#if DEBUG
    SpinWait.SpinUntil(() => Debugger.IsAttached);
#endif 
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 is compatible.  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 was computed. 
.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 (1)

Showing the top 1 NuGet packages that depend on eQuantic.Mapper:

Package Downloads
eQuantic.Core.Application.Crud

eQuantic Application CRUD Library

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.4.0 691 9/18/2024
1.3.6 880 7/23/2024
1.3.5 127 7/22/2024
1.3.4 99 7/22/2024
1.3.3 105 7/22/2024
1.3.2 211 7/20/2024
1.3.1 100 7/15/2024
1.3.0 139 7/1/2024
1.2.8 113 6/28/2024
1.2.7 100 6/28/2024
1.2.6 90 6/28/2024
1.2.5 106 6/28/2024
1.2.4 746 5/5/2024
1.2.3 113 5/4/2024
1.2.2 256 5/4/2024
1.2.1 176 5/3/2024
1.2.0 81 5/3/2024
1.1.9 172 4/23/2024
1.1.8 102 4/23/2024
1.1.7 97 4/23/2024
1.1.6 97 4/23/2024
1.1.5 2,113 11/18/2023
1.1.4 1,463 8/2/2023
1.1.3 574 7/15/2023
1.1.2 175 7/15/2023
1.1.1 164 7/15/2023
1.1.0 303 5/18/2023
1.0.2 316 1/10/2023
1.0.1 307 1/9/2023
1.0.0 312 1/8/2023

DTOs mapping without reflection