Chd (Cleverly Handle Difficulty) packages are easy to use. Automatically maps DTO and Entity classes without any configuration, generating implicit mapping operators at compile time using [MapTo] and optional property-level mapping via [MapProperty].
License
—
Deps
1
Install Size
—
Vulns
✓ 0
Published
Feb 28, 2026
$ dotnet add package Chd.Mapping.RoslynChd (Cleverly Handle Difficulty) library helps you cleverly handle difficulty, write code quickly, and keep your application stable.
Chd.Mapping.Roslyn is a blazing-fast, compile-time source generator for .NET that creates implicit mapping operators between DTO and Entity classes—no reflection, no runtime overhead, just pure performance!
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")].
Chd.Mapping.Roslyn delivers mapping speed, reliability, and maintainability at an enterprise level:
Level up your DTO ↔ Entity mapping with compile-time efficiency!
[MapTo], [MapProperty] (for property name remapping only)Install via .NET CLI:
dotnet add package Chd.Mapping.Roslyn
Or via NuGet Package Manager Console:
Install-Package Chd.Mapping.Roslyn
Or via Package Manager UI in Visual Studio / Rider.
using Chd.Mapping.Abstractions;
// 1. Mark your DTO with [MapTo] attribute
[MapTo(typeof(UserEntity))]
public partial class UserDto
{
public int Id { get; set; }
public string Name { get; set; }
}
// 2. Define your Entity (must be partial)
public partial class UserEntity
{
public int Id { get; set; }
public string Name { get; set; }
}
// 3. Use implicit operators - that's it!
var dto = new UserDto { Id = 1, Name = "Alice" };
UserEntity entity = dto; // DTO → Entity
UserDto dto2 = entity; // Entity → DTO
Console.WriteLine($"Entity: {entity.Id}, {entity.Name}");
Output:
Entity: 1, Alice
✅ No configuration needed! ✅ No reflection overhead! ✅ Full IntelliSense support!
Scenario: Simple DTO ↔ Entity mapping with identical property names.
using System;
using Chd.Mapping.Abstractions;
[MapTo(typeof(UserEntity))]
public partial class UserDto
{
public int Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
}
public partial class UserEntity
{
public int Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
}
class Program
{
static void Main()
{
// DTO to Entity
var dto = new UserDto
{
Id = 1,
Name = "Alice",
Email = "alice@example.com"
};
UserEntity entity = dto;
Console.WriteLine($"Entity: {entity.Id}, {entity.Name}, {entity.Email}");
// Entity back to DTO
UserDto dto2 = entity;
Console.WriteLine($"DTO: {dto2.Id}, {dto2.Name}, {dto2.Email}");
}
}
Console Output:
Entity: 1, Alice, alice@example.com
DTO: 1, Alice, alice@example.com
Scenario: Property names differ between DTO and Entity.
using System;
using Chd.Mapping.Abstractions;
[MapTo(typeof(UserEntity))]
public partial class UserDto
{
public int Id { get; set; }
[MapProperty("FullName")] // Maps to UserEntity.FullName
public string Name { get; set; }
[MapProperty("EmailAddress")] // Maps to UserEntity.EmailAddress
public string Email { get; set; }
}
public partial class UserEntity
{
public int Id { get; set; }
public string FullName { get; set; }
public string EmailAddress { get; set; }
}
class Program
{
static void Main()
{
var dto = new UserDto
{
Id = 42,
Name = "Mehmet Yoldaş",
Email = "mehmet@example.com"
};
UserEntity entity = dto;
Console.WriteLine($"Id: {entity.Id}");
Console.WriteLine($"FullName: {entity.FullName}");
Console.WriteLine($"EmailAddress: {entity.EmailAddress}");
}
}
Console Output:
Id: 42
FullName: Mehmet Yoldaş
EmailAddress: mehmet@example.com
Scenario: Nested DTOs and collections are automatically mapped.
using System;
using System.Collections.Generic;
using Chd.Mapping.Abstractions;
[MapTo(typeof(ProductEntity))]
public partial class ProductDto
{
public string Code { get; set; }
public int Quantity { get; set; }
public decimal Price { get; set; }
}
public partial class ProductEntity
{
public string Code { get; set; }
public int Quantity { get; set; }
public decimal Price { get; set; }
}
[MapTo(typeof(OrderEntity))]
public partial class OrderDto
{
public int OrderId { get; set; }
public string CustomerName { get; set; }
public List<ProductDto> Products { get; set; }
}
public partial class OrderEntity
{
public int OrderId { get; set; }
public string CustomerName { get; set; }
public List<ProductEntity> Products { get; set; }
}
public partial class OrderEntity
{
public int OrderId { get; set; }
public string CustomerName { get; set; }
public List<ProductEntity> Products { get; set; }
}
class Program
{
static void Main()
{
var dto = new OrderDto
{
OrderId = 3,
CustomerName = "Acme Corp",
Products = new List<ProductDto>
{
new ProductDto { Code = "A123", Quantity = 2, Price = 49.99m },
new ProductDto { Code = "B456", Quantity = 5, Price = 29.99m }
}
};
// Automatic nested mapping
OrderEntity entity = dto;
Console.WriteLine($"Order #{entity.OrderId} - Customer: {entity.CustomerName}");
Console.WriteLine("Products:");
foreach (var p in entity.Products)
Console.WriteLine($" {p.Code}: {p.Quantity}x @ ${p.Price}");
}
}
Console Output:
Order #3 - Customer: Acme Corp
Products:
A123: 2x @ $49.99
B456: 5x @ $29.99
✅ Collections are automatically mapped!
✅ Works with List<T>, IEnumerable<T>, arrays, etc.
All mapping code is standard C# and fully debuggable:
View Generated Files:
obj/Debug/netX.X/generated/ folderSet Breakpoints:
implicit operator methodsIntelliSense Support:
Example Generated Code:
public static implicit operator UserEntity(UserDto source)
{
if (source == null) return null;
return new UserEntity
{
Id = source.Id,
FullName = source.Name,
EmailAddress = source.Email
};
}
| 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!
partial[MapTo] on DTO classes targeting your entity type[MapProperty("TargetPropertyName")] only for property name remapping[MapProperty].Price + Tax - Discount.[MapTo] must be declared as partial
MAP001):partial is automatically added for you:
// Incorrect:
[MapTo(typeof(Entity))]
public class MyDto { ... }
// Fixed:
[MapTo(typeof(Entity))]
public partial class MyDto { ... }
partial to your class declaration (public partial class ...)dotnet clean && dotnet build)/obj for generated mapping filesQ: Does this library support custom mapping expressions like Price * Quantity?
A: No. Chd.Mapping.Roslyn only supports:
[MapProperty("TargetName")]Q: Can I debug the generated mapping code?
A: Yes! All generated code is standard C# located in your project's /obj folder. You can:
Q: Is there any runtime dependency or overhead?
A: No! Mapping is 100% compile-time. Zero reflection, zero runtime configuration, just generated C# code.
Q: What .NET versions are supported?
A: Compatible with:
Q: What happens if I forget to add partial to my class?
A: You'll get compiler error MAP001 with a helpful message. Your IDE (Visual Studio, Rider) will offer a one-click quick fix to add partial automatically.
Q: Can I map between classes with different property names?
A: Yes! Use [MapProperty("TargetPropertyName")] attribute:
[MapTo(typeof(Entity))]
public partial class Dto
{
[MapProperty("FullName")]
public string Name { get; set; }
}
Q: What if properties don't match between DTO and Entity?
A: Properties with matching names and compatible types are mapped. Mismatched properties are ignored.
Q: How does performance compare to AutoMapper/Mapster?
A: Chd.Mapping.Roslyn is 2-5x faster because:
Q: Is there any memory overhead?
A: No! Generated operators create objects the same way manual code would. No extra allocations.
Complete working examples with benchmarks, tests, and real-world scenarios:
Includes:
Contributions, issues, and feature requests are welcome! Check issues page or submit a pull request.
Made with ❤️ by Mehmet Yoldaş
🚀 Level up your DTO ↔ Entity mapping with compile-time efficiency!