eQuantic.Mapper.Generator 1.6.0

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

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

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 create delegations for OnBeforeMap or/and OnAfterMap events:

[Mapper(typeof(ExampleA), typeof(ExampleB))]
public partial class ExampleMapper : IMapper
{
    partial void AfterConstructor()
    {
        OnAfterMap += (s, e) => 
        {
            if(e.Source.Name == "Test")
            {
                e.Destination.Name = "Empty";
            }
        };
    }
}

If you need to modify the generated constructor, just set OmitConstructor on attribute and create the new one:

[Mapper(typeof(ExampleA), typeof(ExampleB), OmitConstructor = true)]
public partial class ExampleMapper : IMapper
{
    public ExampleMapper(IMapperFactory mapperFactory)
    {
        MapperFactory = mapperFactory;
        
        OnAfterMap += (s, e) => 
        {
            if(e.Source.Name == "Test")
            {
                e.Destination.Name = "Empty";
            }
        };
    }
}

Debugging

Inside MapperGenerator on Initialize method use:

#if DEBUG
    SpinWait.SpinUntil(() => Debugger.IsAttached);
#endif 
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.6.0 136 2/23/2025
1.5.1 226 1/20/2025
1.5.0 83 1/20/2025
1.4.0 934 9/18/2024
1.3.6 331 7/23/2024
1.3.5 113 7/22/2024
1.3.4 100 7/22/2024
1.3.3 107 7/22/2024
1.3.2 140 7/20/2024
1.3.1 112 7/15/2024
1.3.0 150 7/1/2024
1.2.8 140 6/28/2024
1.2.7 130 6/28/2024
1.2.6 115 6/28/2024
1.2.5 121 6/28/2024
1.2.4 370 5/5/2024
1.2.3 133 5/4/2024
1.2.2 117 5/4/2024
1.2.1 131 5/3/2024
1.2.0 90 5/3/2024
1.1.9 156 4/23/2024
1.1.8 130 4/23/2024
1.1.7 119 4/23/2024
1.1.6 126 4/23/2024
1.1.5 506 11/18/2023
1.1.4 441 8/2/2023
1.1.3 213 7/15/2023
1.1.2 190 7/15/2023
1.1.1 180 7/15/2023
1.1.0 308 5/18/2023
1.0.0 217 1/8/2023

DTOs mapping without reflection