INTRODUCTION · MAPPEReQuantic.MappereQuantic.Mapper maps one object onto another without reflection: the mapping code is generated when you build, so what runs is the code you would have written by hand.
Overview
It handles complex property mappings, aggregations and transformations of your own, all through Roslyn source generators rather than at run time.Property aggregation, type checking while you build, configuration by attribute and dependency injection support all come as standard.
Install it
shell
dotnet add package eQuantic.Mapper
What it does
No reflectionEvery mapping is generated when you build, by a Roslyn source generator.
Property aggregationCombine several source properties into one destination property, with more than a dozen kinds of aggregation.
Type safetyThe types are checked when you build, so a mismatch is a compile error rather than a surprise in production.
Fast by constructionGenerated code with the least allocation it can manage, shaped so the JIT can inline it.
Configured by attributeThe mapping is declared where the property is, and there is no boilerplate to keep in step with it.
Asynchronous mappingFull asynchronous support, cancellation token included.
No reflectionEvery mapping is generated when you build, by a Roslyn source generator.
Property aggregationCombine several source properties into one destination property, with more than a dozen kinds of aggregation.
Type safetyThe types are checked when you build, so a mismatch is a compile error rather than a surprise in production.
Fast by constructionGenerated code with the least allocation it can manage, shaped so the JIT can inline it.
Configured by attributeThe mapping is declared where the property is, and there is no boilerplate to keep in step with it.
Asynchronous mappingFull asynchronous support, cancellation token included.
Quick start
Declare the models — The destination property says where it comes from, and how several sources combine into it.
C#
public class UserSource{ public string FirstName { get; set; } = string.Empty; public string LastName { get; set; } = string.Empty; public decimal Salary { get; set; } public decimal Bonus { get; set; }} public class UserDestination{ [MapFrom(typeof(UserSource), new[] { nameof(UserSource.FirstName), nameof(UserSource.LastName) }, MapperPropertyAggregation.ConcatenateWithSpace)] public string FullName { get; set; } = string.Empty; [MapFrom(typeof(UserSource), new[] { nameof(UserSource.Salary), nameof(UserSource.Bonus) }, MapperPropertyAggregation.Sum)] public decimal TotalIncome { get; set; }}
Generate the mapper — One attribute on a partial class, and the generator writes the mapping.
C#
[Mapper(typeof(UserSource), typeof(UserDestination))]public partial class UserMapper : IMapper{} var builder = WebApplication.CreateBuilder(args);builder.Services.AddMappers(); var mapper = mapperFactory.GetMapper<UserSource, UserDestination>()!;var result = mapper.Map(userSource);
Aggregate several sources — The same attribute takes a different aggregation for each case.
C#
public class PersonDestination{ [MapFrom(typeof(PersonSource), new[] { nameof(PersonSource.FirstName), nameof(PersonSource.LastName) }, MapperPropertyAggregation.ConcatenateWithSpace)] public string FullName { get; set; } = string.Empty; [MapFrom(typeof(PersonSource), new[] { nameof(PersonSource.Salary), nameof(PersonSource.Bonus) }, MapperPropertyAggregation.Sum)] public decimal TotalIncome { get; set; } [MapFrom(typeof(PersonSource), new[] { nameof(PersonSource.Salary), nameof(PersonSource.Bonus) }, MapperPropertyAggregation.Max)] public decimal HighestComponent { get; set; }}
Public surface
NAMESPACE
PUBLIC SURFACE
MapFromAttribute
Declares where a destination property's value comes from, and how the sources aggregate.
MapperAttribute
Marks the partial class the generator should fill with a mapping between two types.
MapperPropertyAggregation
The kinds of aggregation: none, concatenate, sum, maximum, minimum, average, and more.
Prefer reading code?
Every package is MIT and public, and the samples are copy-paste ready.
Ready to ship something real?
Book a 30-minute discovery call. We'll tell you within the hour whether we're the right partner — or who is.
Ready to ship something real?
Book a 30-minute discovery call. We'll tell you within the hour whether we're the right partner — or who is.
© 2026 eQuantic Tech. All rights reserved.