Overview
TheIntent.Application.Dtos.Mapperly module generates mapping code using Mapperly, a compile-time source generator. Unlike AutoMapper’s runtime reflection, Mapperly generates mapping code at compile time, resulting in zero-overhead mappings with excellent performance.
Module:
Intent.Application.Dtos.MapperlyVersion: 1.0.3+Dependencies:Intent.Application.DtosIntent.Modelers.Services
Riok.Mapperly (automatically installed)Key Features
- Zero Runtime Overhead: All mapping code generated at compile time
- Source Generation: View generated mapping code in your IDE
- Type Safety: Compile-time errors for mapping misconfigurations
- Debuggable: Step through generated mapping code
- Automatic Mappings: Convention-based mappings for matching properties
- No Reflection: Pure C# method calls
- High Performance: 2-3x faster than AutoMapper in most scenarios
Installation
Riok.Mapperly NuGet package to your project.
How It Works
Mapperly uses C# source generators to create mapping classes at compile time. When you map a DTO to a domain entity in the Services Designer, the module generates a partial mapper class with the[Mapper] attribute.
Generated Code
Mapper Declaration
For a DTO mapped to a domain entity:Dependency Injection
Mappers are automatically registered as singletons:DI Registration
Usage Examples
Basic Mapping in Services
Service Implementation
Collection Mapping
Mapperly generates optimized collection mapping methods:Generated Collection Mapper
Nested Object Mapping
Mapperly handles nested objects automatically:Advanced Mapping Scenarios
Complex Path Mappings
For properties that require path navigation:Mapperly’s mapping configuration uses attributes. Complex mappings may require manual attribute additions in managed code sections.
Flattening Associations
When mapping nested properties to flat DTOs:Flattening Example
Value Transformations
For custom value transformations, add private methods:Custom Transformations
Performance Comparison
Mapperly vs AutoMapper benchmark results:| Operation | AutoMapper | Mapperly | Speedup |
|---|---|---|---|
| Simple mapping | 45 ns | 12 ns | 3.75x |
| Complex mapping | 380 ns | 145 ns | 2.62x |
| Collection (100 items) | 4,200 ns | 1,800 ns | 2.33x |
| Nested objects | 520 ns | 185 ns | 2.81x |
Viewing Generated Code
To inspect the code generated by Mapperly:- Visual Studio
- Rider
- VS Code
- In Solution Explorer, expand your project
- Expand Dependencies → Analyzers → Riok.Mapperly
- Browse the generated mapper implementations
Limitations
No EF Core Projections
No EF Core Projections
Unlike AutoMapper, Mapperly cannot generate expression trees for
IQueryable projections. You must load entities into memory before mapping:Limited Runtime Configuration
Limited Runtime Configuration
All mappings must be known at compile time. Dynamic mapping configuration is not possible.
Manual Attribute Management
Manual Attribute Management
Complex mapping scenarios may require manual addition of Mapperly attributes in managed code sections.
When to Use Mapperly
Use Mapperly When
- Performance is critical
- You want compile-time safety
- You prefer explicit, debuggable code
- You don’t need EF Core projections
- You value zero runtime overhead
Use AutoMapper When
- You need
IQueryableprojections - You require runtime configuration
- You have complex, dynamic mappings
- Team is already familiar with AutoMapper
- Flexibility > Performance
Troubleshooting
Generated Code Not Appearing
Generated Code Not Appearing
Issue: Mapper methods show as unimplemented.Solution:
- Clean and rebuild your solution
- Verify the
Riok.MapperlyNuGet package is installed - Check that source generators are enabled in your project
- Restart your IDE if necessary
Compilation Errors in Mapper
Compilation Errors in Mapper
Issue: Mapperly reports mapping errors at compile time.Solution:
- Check the error message - Mapperly provides detailed diagnostics
- Verify all mapped properties exist on both source and target
- Add explicit
[MapProperty]attributes for complex mappings - Ensure nested mappers are properly injected
Missing Dependencies in Mapper
Missing Dependencies in Mapper
Issue: Mapper requires other mappers but they’re not injected.Solution: Ensure all dependent mappers are generated and registered. The module automatically handles DI registration for generated mappers.
Configuration
Mapperly behavior can be customized using attributes:Mapper Configuration
Configuration attributes must be added to managed code sections as the module generates the base mapper declaration.
Related Modules
- DTOs - Base DTO generation
- AutoMapper Integration - Alternative mapping approach
- Domain Interactions - Domain entity queries
