Moedim.Mapper 1.0.0-preview.4

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

Moedim.Mapper

C# Source Generator Object Mapper - Convention-based and Attribute-based mapping with compile-time code generation

Build Status NuGet License

Stand With Israel

This is a Hebrew word that translates "feast" or "appointed time." "Appointed times" refers to HaSham's festivals in Vayikra/Leviticus 23rd. The feasts are "signals and signs" to help us know what is on the heart of HaShem.

Features

  • Compile-Time Code Generation - Zero runtime overhead with source generators
  • Attribute-Based Mapping - Simple, declarative mapping configuration
  • Type-Safe - Full compile-time type checking and IntelliSense support
  • Null-Safe - Handles nullable reference types correctly
  • Collection Support - Maps List, Array, IEnumerable, and Dictionary types
  • Custom Property Mapping - Map properties with different names
  • Ignored Properties - Exclude specific properties from mapping
  • High Performance - Faster than reflection-based mappers
  • Multi-Framework Support - Targets .NET 6.0, .NET 7.0, and .NET 8.0

Hire me

Please send email if you consider to hire me.

buymeacoffee

Give a Star! ⭐

If you like or are using this project to learn or start your solution, please give it a star. Thanks!

Installation

dotnet add package Moedim.Mapper

Quick Start

Basic Attribute-Based Mapping

using Moedim.Mapper;

// Source class
public class User
{
    public string Name { get; set; }
    public int Age { get; set; }
    public string Email { get; set; }
}

// Destination class with MapFrom attribute
[MapFrom(typeof(User))]
public class UserDto
{
    public string Name { get; set; }
    public int Age { get; set; }
    public string Email { get; set; }
}

// Usage
var user = new User { Name = "John", Age = 30, Email = "john@example.com" };
var dto = user.ToUserDto(); // Extension method generated automatically

Custom Property Mapping

public class Product
{
    public string ProductName { get; set; }
    public decimal Price { get; set; }
}

[MapFrom(typeof(Product))]
public class ProductDto
{
    [MapProperty("ProductName")]  // Map from different property name
    public string Name { get; set; }
    public decimal Price { get; set; }
}

// Usage
var product = new Product { ProductName = "Laptop", Price = 1299.99m };
var dto = product.ToProductDto();
// dto.Name will contain "Laptop"

Ignoring Properties

public class Employee
{
    public string Name { get; set; }
    public decimal Salary { get; set; }
    public string SocialSecurityNumber { get; set; }
}

[MapFrom(typeof(Employee))]
public class EmployeeDto
{
    public string Name { get; set; }

    [IgnoreProperty]  // Excluded from mapping
    public decimal Salary { get; set; }

    [IgnoreProperty]  // Excluded from mapping
    public string SocialSecurityNumber { get; set; }
}

Collection Mapping

public class Team
{
    public string Name { get; set; }
    public List<string> Members { get; set; }
}

[MapFrom(typeof(Team))]
public class TeamDto
{
    public string Name { get; set; }
    public List<string> Members { get; set; }
}

// Collections are mapped automatically
var team = new Team
{
    Name = "Dev Team",
    Members = new List<string> { "Alice", "Bob" }
};
var dto = team.ToTeamDto();

Bidirectional Mapping

// Map in both directions
[MapTo(typeof(PersonDto))]
public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

[MapFrom(typeof(Person))]
public class PersonDto
{
    public string Name { get; set; }
    public int Age { get; set; }
}

// Now both directions work
var person = new Person { Name = "Alice", Age = 25 };
var dto = person.ToPersonDto();
var personAgain = dto.ToPerson();

Generated Code Example

For the basic User/UserDto example, Moedim.Mapper generates:

// <auto-generated/>
#nullable enable

using TestNamespace;

namespace TestNamespace;

/// <summary>
/// Extension methods for mapping User to UserDto.
/// </summary>
public static class UserToUserDtoMappingExtensions
{
    /// <summary>
    /// Maps User to UserDto.
    /// </summary>
    public static UserDto? ToUserDto(this User? source)
    {
        if (source is null)
            return null;

        return new UserDto
        {
            Name = source.Name,
            Age = source.Age,
            Email = source.Email
        };
    }
}

Performance

Moedim.Mapper uses source generators to create mapping code at compile time, resulting in:

  • Zero reflection overhead - Direct property assignments
  • Similar to manual mapping - Generated code is as fast as hand-written code
  • No runtime initialization - Ready to use immediately
  • Optimized for collections - Efficient collection transformations

Run benchmarks with:

dotnet run --project tests/Moedim.Mapper.Performance.Tests -c Release

Advanced Features

Fluent Configuration Interface

public interface IMapperConfigurationBuilder
{
    IMappingExpression<TSource, TDestination> CreateMap<TSource, TDestination>();
}

public interface IMappingExpression<TSource, TDestination>
{
    IMappingExpression<TSource, TDestination> ForMember<TMember>(
        Expression<Func<TDestination, TMember>> destinationMember,
        Action<IMemberConfigurationExpression<TSource, TDestination, TMember>> memberOptions);
}

Supported Type Conversions

  • Direct type matches
  • Nullable value types (int to int?, etc.)
  • Collection types (Array, List, IEnumerable)
  • Numeric conversions (int to long, etc.)

Requirements

  • .NET 6.0, 7.0, or 8.0
  • C# 11 or later (for consuming projects)
  • Visual Studio 2022 or Rider (for best IDE support)

Project Structure

  • Moedim.Mapper - Core library with attributes and interfaces
  • Moedim.Mapper.SourceGenerator - Roslyn source generator implementation
  • Moedim.Mapper.Tests - Unit tests
  • Moedim.Mapper.SourceGenerator.Tests - Generator-specific tests
  • Moedim.Mapper.Performance.Tests - Performance benchmarks
  • Moedim.Mapper.Sample - Example usage

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Acknowledgments

Built with:

Version History

1.0.0 (Initial Release)

  • Attribute-based mapping with [MapFrom] and [MapTo]
  • Custom property mapping with [MapProperty]
  • Property exclusion with [IgnoreProperty]
  • Collection mapping support
  • Null-safe code generation
  • Multi-framework support (.NET 6.0, 7.0, 8.0)
Product Compatible and additional computed target framework versions.
.NET net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 is compatible.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net6.0

    • No dependencies.
  • net7.0

    • No dependencies.
  • net8.0

    • No dependencies.

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
1.0.1 268 11/13/2025
1.0.0-preview.6 222 11/13/2025
1.0.0-preview.4 219 11/12/2025