Skip to content

iron-mapper/IronMapper

Repository files navigation

IronMapper

NuGet Build License: MIT

📖 Русская документация

Zero-reflection, compile-time object mapper for .NET.

IronMapper generates all mapping code at build time using a Roslyn Source Generator — no runtime reflection, no IL emit, no dynamic proxies. Just plain, readable, debuggable C# that the compiler can optimize like any other code.


vs AutoMapper

Feature AutoMapper IronMapper
Mapping strategy Reflection at runtime Source-generated C# at compile time
Misconfiguration detected At app startup At dotnet build
NativeAOT / IL trimming Requires annotations Fully compatible
Performance ~2–5 µs / object ~0 ns overhead
License MIT MIT
API style Profile-based fluent API Attributes or Profile-based fluent API
Package size ~500 KB ~30 KB

Quick Start (5 minutes)

1. Install

dotnet add package IronMapper

2. Annotate your source type

using IronMapper.Attributes;

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

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

3. Map

var entity = new UserEntity { Id = 1, Name = "Alice", Email = "alice@example.com" };
UserDto dto = entity.MapToUserDto();  // generated extension method

That's it. No IMapper, no service registration, no startup overhead.


Key Features

Attribute-based mapping

[MapTo(typeof(ProductDto))]      // source → dest
[MapFrom(typeof(ProductEntity))] // dest ← source (equivalent)

Property renaming

[MapProperty("FullName")]
public string Name { get; set; } = "";  // maps to FullName on destination

Ignore properties

[Ignore]
public string InternalSecret { get; set; } = "";

Custom type converters

public class PriceConverter : ITypeConverter<decimal, string>
{
    public string Convert(decimal source) => source.ToString("F2");
}

[MapTo(typeof(InvoiceDto))]
public class Invoice
{
    [MapConverter(typeof(PriceConverter))]
    public decimal Total { get; set; }
}

Profile-based fluent API

public class OrderProfile : MappingProfile
{
    public OrderProfile()
    {
        CreateMap<OrderEntity, OrderDto>()
            .ForMember(d => d.FullAddress, o => o.MapFrom(s => s.Street + ", " + s.City))
            .ForMember(d => d.InternalId,  o => o.Ignore());
    }
}

Collection helpers

List<UserEntity> entities = ...;
List<UserDto>    dtos = entities.MapToUserDtoList();
UserDto[]        arr  = entities.MapToUserDtoArray();

In-place (void) mapping

entity.MapToUserDto(existingDto);  // updates existing object without allocating a new one

Nested collections

[MapTo(typeof(BlogDto))]
public class BlogEntity
{
    public List<CommentEntity> Comments { get; set; } = new();
}
// generator emits: Comments = Enumerable.ToList(Enumerable.Select(source.Comments, x => x.MapToCommentDto()))

ASP.NET Core DI

// Program.cs
builder.Services.AddIronMapper(typeof(Program).Assembly);

// In a controller / service
public class OrdersController(IMapper mapper) : ControllerBase
{
    public OrderDto Get(int id) => mapper.Map<OrderDto>(_repo.GetById(id));
}

Demo Application

We've built a sample console app that showcases all IronMapper features using the real Open Library API (no API key required).

What the demo covers:

  • Simple attribute-based mapping ([MapTo])
  • Fluent API with MappingProfile
  • Collection mapping (List<BookDoc>List<BookSummary>)
  • Nested object mapping (Book + Author)
  • Custom type converters (HTML bio cleaner)
  • Conditional mapping (living authors only)

Run it:

git clone https://github.com/iron-mapper/IronMapper
cd IronMapper
dotnet run --project samples/IronMapper.Demo

Documentation


Contributing

Contributions are welcome! Please:

  1. Fork the repo and create a feature branch (feature/my-feature).
  2. Make your changes with tests.
  3. Run dotnet build and dotnet test — both must be clean.
  4. Open a pull request against main.

Please follow the existing code style (see .editorconfig).


License

MIT © Iron Programmer School

About

Zero-reflection, compile-time object mapper for .NET 10. Free alternative to AutoMapper. By Iron Programmer School.

Topics

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages