High-performance, type-safe, and extensible object mapping library for .NET
$ dotnet add package ForgeSharp.MapperForgeSharp.Mapper is a high-performance, type-safe, and extensible object mapping library for .NET. It enables you to define, configure, and execute mappings between different object types using a fluent, strongly-typed API. The library is designed for speed, maintainability, and ease of integration with modern .NET applications.
ForgeSharp.Mapper.DependencyInjection NuGet.At the time of writing, ForgeSharp.Mapper is significantly faster than other popular mapping libraries. Below is a benchmark* comparison against AutoMapper, Mapster, and manual mapping:
| Method | Mean | Error | StdDev | Ratio | RatioSD |
|---|---|---|---|---|---|
| Manual | 5.321 ns | 0.1659 ns | 0.3942 ns | 1.01 | 0.10 |
| ForgeSharp.Mapper | 11.809 ns | 0.2449 ns | 0.2291 ns | 2.23 | 0.16 |
| Mapster | 21.771 ns | 0.4347 ns | 0.8977 ns | 4.11 | 0.34 |
| AutoMapper | 68.273 ns | 1.4161 ns | 2.2047 ns | 12.90 | 1.01 |
Forgesharp.Mapper is:
Despite its simplicity and lightweight footprint, ForgeSharp.Mapper delivers the same core functionality as other major mappers:
*The full benchmark project is included in the repository for reproducibility.
Add the NuGet package to your project:
dotnet add package ForgeSharp.Mapper
For Dependency Injection support, also install:
dotnet add package ForgeSharp.Mapper.DependencyInjection
This mapping solution can be used in two ways: with Dependency Injection or without it.
public class MyMapperBuilder : MapperBuilder
{
public MyMapperBuilder()
{
Register<Source, Destination>()
.To(d => d.Name).From(s => s.SourceName)
.To(d => d.Age).From((s, d) => s.Years + 1);
}
}
Without Dependency Injection, you can create the IMapperService directly from the builder:
var mapper = new MyMapperBuilder().BuildService();
mapper.Map<Source, Destination>(sourceObject);
This requires the ForgeSharp.Mapper.DependencyInjection NuGet package.
services.AddMapper<MyMapperBuilder>();
var mapper = serviceProvider.GetRequiredService<IMapperService>();
var destination = mapper.Map<Source, Destination>(sourceObject);
The Configure extension method allows you to define complex mappings in a single, expressive member-initializer expression. This makes your mapping configuration more readable and maintainable, especially for larger objects.
Register<Source, Destination>()
.Configure((src, dest) => new Destination
{
Name = src.SourceName,
Age = src.Years + 1,
IsActive = true
});
You can also use Configure for context-aware mappings:
RegisterWithContext<Source, MyContext, Destination>()
.Configure((src, ctx, dest) => new Destination
{
Name = src.SourceName,
UserId = ctx.CurrentUser,
IsActive = true
});
This just uses reflection to handle the fluent API, but the actual mapping is still compiled to delegates for performance.
Register<MyType, MyType>().UseReflectionToClone();
var tester = serviceProvider.GetRequiredService<IMapperTester>();
foreach (var result in tester.ValidateMissingProperties())
{
Console.WriteLine(result);
}
register.AddAssignment(
typeof(Destination).GetProperty(nameof(Destination.SomeProperty)),
(Expression<Func<Source, string>>)(s => s.SomeSourceProperty)
);
ForgeSharpMapper supports context-aware mappers, allowing you to inject a custom context object into the mapping logic.
public class MyContext(Guid currentUser)
{
public Guid CurrentUser { get; set; } = currentUser;
}
This context can then be injected into the mapping logic:
RegisterWithContext<Source, MyContext, Destination>()
.To(d => d.UserId).From((s, ctx) => ctx.CurrentUser)
.To(d => d.Name).From(s => s.SourceName);
MapperRegistry.cs – Core fluent mapping API and registry.MapperService.cs – Service and DI integration.MapperTester.cs – Validation and diagnostics.Reflection/ – Extensions for reflection-based and advanced mapping.Contributions are welcome! Please open issues or submit pull requests for bug fixes, improvements, or new features.
For questions, suggestions, or support, please open an issue on GitHub.
ForgeSharp.Mapper – Fast, type-safe, and extensible mapping for .NET.