LoMapper 0.3.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package LoMapper --version 0.3.0
                    
NuGet\Install-Package LoMapper -Version 0.3.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="LoMapper" Version="0.3.0">
  <PrivateAssets>all</PrivateAssets>
  <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="LoMapper" Version="0.3.0" />
                    
Directory.Packages.props
<PackageReference Include="LoMapper">
  <PrivateAssets>all</PrivateAssets>
  <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add LoMapper --version 0.3.0
                    
#r "nuget: LoMapper, 0.3.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.
#:package LoMapper@0.3.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=LoMapper&version=0.3.0
                    
Install as a Cake Addin
#tool nuget:?package=LoMapper&version=0.3.0
                    
Install as a Cake Tool

LoMapper

A tiny, focused object mapper — Generate mapping code at compile time using Roslyn Source Generators.

NuGet NuGet Downloads Build Status License: MIT .NET GitHub Stars

What is LoMapper?

LoMapper is a small library that generates mapping code at compile time, saving you from writing repetitive property-by-property assignments by hand.

Benefits:

  • Less boilerplate — Stop writing manual property assignments
  • Compile-time safety — Catch mapping issues during build, not at runtime
  • Zero runtime overhead — No reflection, no scanning, just generated code
  • Debuggable — F12 into generated code like it's your own
  • Simple — Just add attributes to partial classes

Quick Start

Installation

dotnet add package LoMapper

Basic Usage

using LoMapper;

// 1. Define your types
public class UserEntity
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Email { get; set; }
}

public class UserDto
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Email { get; set; }
}

// 2. Create a mapper
[Mapper]
public partial class UserMapper
{
    public partial UserDto Map(UserEntity entity);
}

// 3. Use it
var mapper = new UserMapper();
var dto = mapper.Map(entity);

That's it! The Map method is generated at compile time with property-by-property assignment.

Features

Property Mapping

Properties are matched by name (case-insensitive):

public class Source { public int ID { get; set; } }
public class Target { public int Id { get; set; } }  // ✅ Matched

Custom Property Mapping

Rename properties or apply transforms:

[Mapper]
public partial class UserMapper
{
    [MapProperty("FirstName", "FullName")]
    [MapProperty("BirthDate", "Age", Transform = nameof(CalculateAge))]
    public partial UserDto Map(UserEntity entity);

    private int CalculateAge(DateTime birthDate) 
        => DateTime.Today.Year - birthDate.Year;
}

Ignore Properties

Skip properties you don't want mapped:

[Mapper]
public partial class UserMapper
{
    [MapIgnore("InternalId")]
    [MapIgnore("CacheKey")]
    public partial UserDto Map(UserEntity entity);
}

Flatten Properties

Map nested object properties to flat target properties:

[Mapper]
public partial class UserMapper
{
    [FlattenProperty("Address.City", nameof(UserDto.AddressCity))]
    [FlattenProperty("Address.ZipCode", nameof(UserDto.AddressZipCode))]
    public partial UserDto Map(UserEntity entity);
}

Features:

  • ✅ Deep nesting support (e.g., Order.Customer.Address.City)
  • ✅ Null-safe navigation (?.) automatically generated
  • ✅ Type-safe with compile-time validation
  • ✅ Works with both reference and value types
  • ✅ Combine with [MapProperty] and [MapIgnore]

Flatten Properties

Map nested object properties to flat target properties:

[Mapper]
public partial class UserMapper
{
    [FlattenProperty("Address.City", nameof(UserDto.AddressCity))]
    [FlattenProperty("Address.ZipCode", nameof(UserDto.AddressZipCode))]
    public partial UserDto Map(UserEntity entity);
}

Features:

  • ✅ Deep nesting support (e.g., Order.Customer.Address.City)
  • ✅ Null-safe navigation (?.) automatically generated
  • ✅ Type-safe with compile-time validation
  • ✅ Works with both reference and value types
  • ✅ Combine with [MapProperty] and [MapIgnore]

Nested Objects

For nested objects, declare explicit mapper methods:

[Mapper]
public partial class OrderMapper
{
    public partial OrderDto Map(OrderEntity entity);
    public partial CustomerDto Map(CustomerEntity entity);  // Used for nested Customer
    public partial AddressDto Map(AddressEntity entity);    // Used for nested Address
}

Collections

Full support for collections — List<T>, IEnumerable<T>, Dictionary<K,V>, HashSet<T>, and arrays:

public class Source { public List<ItemEntity> Items { get; set; } }
public class Target { public List<ItemDto> Items { get; set; } }  // ✅ Auto-mapped

Compile-Time Diagnostics

LoMapper catches mapping issues before your code runs:

Code Severity Description
LOM001 ⚠️ Warning Target property has no matching source property
LOM002 ❌ Error Property types are incompatible
LOM003 ❌ Error Nested object requires mapper method
LOM004 ❌ Error Invalid transform method signature
LOM005 ❌ Error Source property not found
LOM006 ❌ Error Target property not found
LOM007 ❌ Error Invalid flatten property path
LOM008 ❌ Error Flatten target property not found
LOM009 ❌ Error Flatten type mismatch
LOM004 ❌ Error Invalid transform method signature
LOM005 ❌ Error Source property not found
LOM006 ❌ Error Target property not found
LOM007 ❌ Error Invalid flatten property path
LOM008 ❌ Error Flatten target property not found
LOM009 ❌ Error Flatten type mismatch

Example:

public class Source { public int Id { get; set; } }
public class Target { public int Id { get; set; } public string Extra { get; set; } }

// ⚠️ LOM001: Target property 'Extra' has no matching source property

Benchmarks

**LPerformance

LoMapper generates efficient code that performs well. Benchmark results mapping 10,000 objects:

Method Mean Memory
LoMapper 174 μs 781 KB
Manual 208 μs 781 KB

LoMapper matches the performance and memory characteristics of hand-written mapping code.

The generated code uses straightforward property assignments with no reflection or runtime overhead. For most applications, the performance is more than sufficient and comparable to writing the mappings yourself.

<details> <summary>Full Benchmark Details (Click to expand)</summary>

Tested on Intel Core i7-10870H, .NET 8.0.23, Windows 11 using BenchmarkDotNet v0.14.0.

100 items: 1.67 μs
1,000 items: 15.5 μs
10,000 items: 174 μs

The generated code produces clean IL that the JIT compiler can optimize effectively. Zero allocations beyond the mapped objects themselves.

Full Results </details>

cd benchmarks/LoMapper.Benchmarks
dotnet run -c Release

View Generated Code

Enable generated file output in your .csproj:

<PropertyGroup>
  <EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
</PropertyGroup>

Find generated files in: obj/GeneratedFiles/LoMapper.Generator/

Comparison

Feature LoMapper Manual Code
Performance (10K items) 174 μs 208 μs
Memory overhead 0% -
Compile-time generation N/A
Zero runtime reflection
Compile-time error detection
IntelliSense support
Nested object mapping
Collection mapping
Custom transforms
Flattening/unflattening ✅ v0.3 Manual
Projection (IQueryable) 🔜 v1.0 Manual

Why Use LoMapper?

vs Writing Mappings Manually:

  • Less repetitive code to write and maintain
  • Compile-time validation catches errors early
  • Automatic updates when models change
  • Similar or better performance

When LoMapper Might Help:

  • You have many DTOs to map
  • You want compile-time safety without runtime cost
  • You prefer code generation over reflection
  • You like seeing exactly what code runs (F12 into generated code)

Current Limitations:

  • Expression projection for IQueryable not yet supported (planned for v1.0)
  • Some advanced mapping scenarios may need manual code

LoMapper is a focused tool that does one thing well: generate simple, efficient mapping code. It's meant to complement your toolkit, not replace everything else.

Requirements

  • .NET Standard 2.0+ (runs on .NET Core 3.1+, .NET 5+, .NET Framework 4.7.2+)
  • C# 9.0+ (for partial methods)

Contributing

Contributions are welcome! Please read our Contributing Guide first.

License

MIT License - see LICENSE for details.


LoMapper — A tiny tool to help you write less mapping code.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  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 was computed.  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.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.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.
  • .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
0.4.0 93 1/19/2026
0.3.0 96 1/19/2026
0.2.0 95 1/17/2026
0.1.1 95 1/17/2026