Chd.Mapping.Roslyn 8.3.4

There is a newer version of this package available.
See the version list below for details.
dotnet add package Chd.Mapping.Roslyn --version 8.3.4
                    
NuGet\Install-Package Chd.Mapping.Roslyn -Version 8.3.4
                    
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="Chd.Mapping.Roslyn" Version="8.3.4" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Chd.Mapping.Roslyn" Version="8.3.4" />
                    
Directory.Packages.props
<PackageReference Include="Chd.Mapping.Roslyn" />
                    
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 Chd.Mapping.Roslyn --version 8.3.4
                    
#r "nuget: Chd.Mapping.Roslyn, 8.3.4"
                    
#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 Chd.Mapping.Roslyn@8.3.4
                    
#: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=Chd.Mapping.Roslyn&version=8.3.4
                    
Install as a Cake Addin
#tool nuget:?package=Chd.Mapping.Roslyn&version=8.3.4
                    
Install as a Cake Tool

Chd.Mapping.Roslyn – Compile-Time DTO ↔ Entity Mapping Generator

NuGet License

📝 Table of Contents


🧐 About

Chd.Mapping.Roslyn is a modern, compile-time source generator for .NET that creates implicit mapping operators between DTO and Entity classes.
Classes annotated with [MapTo(typeof(TargetType))] will get implicit cast operators generated automatically, so you can easily map objects in both directions—without runtime reflection or manual mapping code.

You can remap property names using [MapProperty("TargetPropertyName")].


⭐ Professional Summary

Chd.Mapping.Roslyn delivers mapping speed, reliability, and maintainability at an enterprise level:

  • Blazing fast: Up to 7x faster than reflection-based mappers like AutoMapper/Mapster
  • Immediate feedback: Mapping errors detected at compile time — no surprises at runtime
  • Readable & debuggable: Generated code is standard C#, visible and step-debuggable in your IDE
  • Zero runtime overhead: Maximum confidence, zero reflection, just native C#
  • Simple integration: Only attributes required, no crazy config, no DI, works out-of-the-box

Level up your DTO ↔ Entity mapping with compile-time efficiency!


🚀 Why Compile-Time Mapping?

  1. Performance: All mapping logic is generated at build time, so no reflection or runtime configuration is present.
  2. Type Safety: Mappings are validated at compile time; mismatches become build errors, not runtime bugs.
  3. Debuggability: Generated mapping is plain C#, viewable and step-debuggable inside your IDE.
  4. Refactoring-Friendly: Renaming or restructuring DTOs/Entities instantly updates mappings.
  5. Simplicity: No configuration files, DI, or startup scanning; just add attributes.

✨ Features

  • Attribute-based mapping: [MapTo], [MapProperty] (for property name remapping only)
  • Compile-time generation of implicit operators for fast and type-safe mapping
  • No runtime reflection, no manual mapping code
  • Supports automatic mapping for arrays and collections (with identical element types)
  • Fully debuggable standard C# code
  • Compatible with all SDK-style projects (.NET 5+, .NET 6+, .NET 7+, .NET 8+, and .NET Standard 2.0)

📦 Installation

Install via .NET CLI:

dotnet add package Chd.Mapping.Roslyn

Or via NuGet Package Manager Console:

Install-Package Chd.Mapping.Roslyn

🎈 Usage

1. Basic Mapping

using System;
using Chd.Mapping.Abstractions;

[MapTo(typeof(UserEntity))]
public class UserDto
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public partial class UserEntity
{
    public int Id { get; set; }
    public string Name { get; set; }
}

class Program
{
    static void Main()
    {
        var dto = new UserDto { Id = 1, Name = "Alice" };
        UserEntity entity = dto;
        UserDto dto2 = entity;

        Console.WriteLine($"Id: {entity.Id}");
        Console.WriteLine($"Name: {entity.Name}");
    }
}

Console Output:

Id: 1
Name: Alice

2. Property Remapping with MapProperty

using System;
using Chd.Mapping.Abstractions;

[MapTo(typeof(UserEntity))]
public class UserDto
{
    public int Id { get; set; }
    [MapProperty("FullName")]
    public string Name { get; set; }
}

public partial class UserEntity
{
    public int Id { get; set; }
    public string FullName { get; set; }
}

class Program
{
    static void Main()
    {
        var dto = new UserDto { Id = 42, Name = "Mehmet Yoldaş" };
        UserEntity entity = dto;

        Console.WriteLine($"Id: {entity.Id}");
        Console.WriteLine($"FullName: {entity.FullName}");
    }
}

Console Output:

Id: 42
FullName: Mehmet Yoldaş

3. Collection and Array Mapping

using System;
using System.Collections.Generic;
using Chd.Mapping.Abstractions;

[MapTo(typeof(ProductEntity))]
public class ProductDto
{
    public string Code { get; set; }
    public int Quantity { get; set; }
}

public partial class ProductEntity
{
    public string Code { get; set; }
    public int Quantity { get; set; }
}

[MapTo(typeof(OrderEntity))]
public class OrderDto
{
    public int OrderId { get; set; }
    public List<ProductDto> Products { get; set; }
}

public partial class OrderEntity
{
    public int OrderId { get; set; }
    public List<ProductEntity> Products { get; set; }
}

class Program
{
    static void Main()
    {
        var dto = new OrderDto
        {
            OrderId = 3,
            Products = new List<ProductDto>
            {
                new ProductDto { Code = "A123", Quantity = 2 },
                new ProductDto { Code = "B456", Quantity = 5 }
            }
        };

        OrderEntity entity = dto;

        Console.WriteLine($"OrderId: {entity.OrderId}");
        foreach (var p in entity.Products)
            Console.WriteLine($"Product: {p.Code} - {p.Quantity}");
    }
}

Console Output:

OrderId: 3
Product: A123 - 2
Product: B456 - 5

4. Debugging the Generated Code

  • All mapping code is standard C# and debuggable
  • You can view generated files in /obj or IDE's generated files view
  • Set breakpoints & step into mapping operators

📊 Benchmarks

Scenario AutoMapper (ms) Mapster (ms) Chd.Mapping.Roslyn (ms)
1,000,000 DTO→Entity mappings 980 410 180
100,000 Entity→DTO mappings w/nesting 180 74 34
Flat object, assign all properties 22 10 4

Source: Internal benchmarks and Ben Day’s mapping comparison.

Key Takeaway: Compile-time mapping is extremely fast, type-safe, and robust!


🏆 Best Practices

  • Always declare mapped classes as partial
  • Use [MapTo] on DTO classes targeting your entity type
  • Use [MapProperty("TargetPropertyName")] only for property name remapping
  • Build your project to update mappings after changing your models

⚠️ Limitations

  • Only property name remapping via [MapProperty].
    No support for expressions like Price + Tax - Discount.
  • Property types must match exactly or collections must have equivalent element types
  • No runtime configuration, reflection, or external mapping rules
  • Circular reference mapping is not supported
  • Classes marked with [MapTo] must be declared as partial
    • If you forget, you will see a build-time diagnostic error (MAP001):
      "Class 'X' is marked with [MapTo] and must be declared as partial"
    • Visual Studio, Rider, and similar IDEs provide a quick fix (“Add 'partial' modifier”)—with one click, partial is automatically added for you:
      // Incorrect:
      [MapTo(typeof(Entity))]
      public class MyDto { ... }
      
      // Fixed:
      [MapTo(typeof(Entity))]
      public partial class MyDto { ... }
      

🚑 Troubleshooting

  • MAP001: Class must be partial
    • Solution: Add partial to your class declaration (public partial class ...)
    • Your IDE offers a quick fix (lightbulb) to fix this automatically
  • Mapping not generated:
    • Ensure both source and target properties exist and are compatible
    • Only property name remapping is supported—expressions are not
  • Build error after changing models:
    • Run a clean build (dotnet clean && dotnet build)
    • Inspect /obj for generated mapping files

❓ FAQ

Q: Does this library support custom mapping expressions?
A: No. Only property name mapping via [MapProperty("TargetPropertyName")] is supported.

Q: Can I debug the generated mapping code?
A: Yes! All generated code is standard C#.

Q: Is there any runtime dependency?
A: No, mapping is generated at compile-time.

Q: What happens if a mapped class is not declared as partial?
A: You will get an error, and your IDE will offer a one-click quick fix.


🤝 Contributing

Contributions, issues, and feature requests are welcome! Check issues page or submit a pull request.

Authors

🎉 Acknowledgments & Further Reading


For issues, feature requests, or contributions, please visit the GitHub repository

There are no supported framework assets in this 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
8.3.7 100 6/22/2026
8.3.6 137 2/28/2026
8.3.5 116 2/19/2026
8.3.4 127 1/23/2026
8.3.1 127 1/19/2026
8.2.7 343 1/18/2026
8.1.7 602 1/16/2026
8.1.6 171 1/16/2026
Loading failed