AlephMapper 0.3.8

There is a newer version of this package available.
See the version list below for details.
dotnet add package AlephMapper --version 0.3.8
                    
NuGet\Install-Package AlephMapper -Version 0.3.8
                    
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="AlephMapper" Version="0.3.8">
  <PrivateAssets>all</PrivateAssets>
  <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="AlephMapper" Version="0.3.8" />
                    
Directory.Packages.props
<PackageReference Include="AlephMapper">
  <PrivateAssets>all</PrivateAssets>
  <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
                    
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 AlephMapper --version 0.3.8
                    
#r "nuget: AlephMapper, 0.3.8"
                    
#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 AlephMapper@0.3.8
                    
#: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=AlephMapper&version=0.3.8
                    
Install as a Cake Addin
#tool nuget:?package=AlephMapper&version=0.3.8
                    
Install as a Cake Tool

Stand With Ukraine

Terms of use<sup>?</sup>

By using this project or its source code, for any purpose and in any shape or form, you grant your implicit agreement to all the following statements:

  • You condemn Russia and its military aggression against Ukraine
  • You recognize that Russia is an occupant that unlawfully invaded a sovereign state
  • You support Ukraine's territorial integrity, including its claims over temporarily occupied territories of Crimea and Donbas
  • You reject false narratives perpetuated by Russian state propaganda

To learn more about the war and how you can help, click here. Glory to Ukraine! πŸ‡ΊπŸ‡¦

AlephMapper

NuGet License

AlephMapper is a Source Generator that automatically creates projectable and/or updatable companion methods from your mapping logic. It enables you to write mapping methods once and use them both for in-memory objects and as expression trees for database queries (Entity Framework Core projections).

πŸš€ Features

  • Expression Tree Generation - Automatically converts method bodies to expression trees
  • Null-Conditional Operator Support - Configurable handling of ?. operators
  • Updatable Methods - Generate update methods that modify existing instances

πŸ“¦ Installation

dotnet add package AlephMapper

πŸƒβ€β™‚οΈ Quick Start

1. Mark your mapping class or method with [Expressive]. Please ensure that your class is static and partial.

public static partial class PersonMapper
{
    [Expressive]
    public static PersonDto MapToPerson(Employee employee) => new PersonDto
    {
        Id = employee.EmployeeId,
        FullName = GetFullName(employee),
        Email = employee.ContactInfo.Email,
        Age = CalculateAge(employee.BirthDate),
        Department = employee.Department?.Name ?? "Unknown"
    };

    public static string GetFullName(Employee employee) => 
        $"{employee.FirstName} {employee.LastName}";

    public static int CalculateAge(DateTime birthDate) => 
        DateTime.Now.Year - birthDate.Year;
}

2. AlephMapper will generate the following method for you:

partial class PersonMapper 
{
    public static Expression<Func<Employee, PersonDto>> MapToPersonExpression() => employee => new PersonDto
    {
        Id = employee.EmployeeId,
        FullName = $"{employee.FirstName} {employee.LastName}",
        Email = employee.ContactInfo.Email,
        Age = DateTime.Now.Year - employee.BirthDate.Year,
        Department = employee.Department.Name ?? "Unknown"
    };
}

3. Use generated expression methods in Entity Framework queries

// The source generator creates PersonMapper.MapToPersonExpression() automatically
var personDtos = await dbContext.Employees
    .Select(PersonMapper.MapToPersonExpression())
    .ToListAsync();

4. Use the original methods for in-memory operations

var employee = GetEmployee();
var personDto = PersonMapper.MapToPerson(employee);
var fullName = PersonMapper.GetFullName(employee);

πŸ”§ Advanced Features

Null-Conditional Operator Handling

AlephMapper provides flexible handling of null-conditional operators (?.):

[Expressive(NullConditionalRewrite = NullConditionalRewrite.Rewrite)]
public static partial class SafeMapper
{
    // This method uses null-conditional operators
    public static PersonSummary GetSummary(Person person) => new PersonSummary
    {
        Name = person.Name,
        Age = person.BirthInfo?.Age,
        City = person.BirthInfo?.Address?.City,
        HasAddress = person.BirthInfo?.Address != null
    };
}

Rewrite Options:

  • None - Don't allow null-conditional operators (throws compile error)
  • Ignore - Remove null-conditional operators (may cause NullReferenceException)
  • Rewrite - Convert to explicit null checks: person.BirthInfo?.Age becomes person.BirthInfo != null ? person.BirthInfo.Age : null

Updatable Methods

From a single mapping, AlephMapper can emit an update-in-place overload that writes into an existing instance (instead of creating a new one). This is especially suitable for EF Core entity updates with change tracking: you keep the same tracked instance, so EF can detect modified properties and produce the correct UPDATE.

[Updatable]
public static Person MapToPerson(PersonUpdateDto dto) => new Person
{
    FirstName = dto.FirstName,
    LastName  = dto.LastName,
    Email     = dto.Email
    // ...
};

// Generated usage with EF Core change tracking:
var person = await db.People.FindAsync(id);           // tracked entity
PersonMapper.MapToPerson(dto, target: person); // mutate in-place
await db.SaveChangesAsync();                           // EF sees changes on the same instance

πŸ” How It Works

For each method marked with [Expressive]:

  1. MapToPersonDto(Employee employee) β†’ generates MapToPersonDtoExpression() returning Expression<Func<Employee, PersonDto>>
  2. Method calls are inlined - Calls to other methods are automatically inlined into the expression tree
  3. Null-conditional operators are handled according to your specified rewrite policy

For each method marked with [Updatable]:

  1. MapToPersonDto(Employee employee) β†’ generates MapToPersonDto(Employee employee, PersonDto target) returning PersonDto
  2. Method calls are inlined - Calls to other methods in the same class are automatically inlined into the method

⚠️ Limitations

Methods must be:

πŸ”„ Migration from Other Mappers

From AutoMapper

// AutoMapper
CreateMap<Employee, PersonDto>()
    .ForMember(dest => dest.FullName, opt => opt.MapFrom(src => src.FirstName + " " + src.LastName));

// AlephMapper
[Expressive]
public static partial class PersonMapper
{
    public static PersonDto MapToPerson(Employee employee) => new PersonDto
    {
        FullName = employee.FirstName + " " + employee.LastName,
        // ... other mappings
    };
}

From Manual Expression Trees

// Manual Expression Trees
Expression<Func<Employee, PersonDto>> expression = e => new PersonDto
{
    FullName = e.FirstName + " " + e.LastName
};

// AlephMapper - Same result, but with method reusability
[Expressive]
public static partial class PersonMapper
{
    public static PersonDto MapToPerson(Employee employee) => new PersonDto
    {
        FullName = GetFullName(employee) // This gets inlined in the expression
    };
    
    public static string GetFullName(Employee employee) => 
        employee.FirstName + " " + employee.LastName;
}

🀝 Contributing

We welcome contributions!

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests for new functionality
  5. Run the test suite
  6. Submit a pull request

πŸ“„ License

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

πŸ™ Acknowledgments


Star ⭐ this repository if AlephMapper helps you build better applications!

There are no supported framework assets in this package.

Learn more about Target Frameworks and .NET Standard.

  • .NETStandard 2.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
0.5.2 87 1/4/2026
0.5.1 88 1/4/2026
0.5.0 219 12/14/2025
0.4.4 211 11/22/2025
0.4.3 307 11/21/2025
0.4.2 365 11/21/2025
0.4.1 401 11/20/2025
0.4.0 164 11/15/2025
0.3.9 162 11/15/2025
0.3.8 169 11/15/2025
0.3.7 186 11/15/2025
0.3.6 285 11/11/2025
0.3.5 146 11/8/2025
0.3.4 138 11/8/2025
0.3.3 145 11/8/2025
0.3.2 202 11/2/2025
0.3.1 193 11/2/2025
0.3.0 132 11/1/2025
0.2.9 174 10/26/2025
0.2.8 183 10/26/2025
0.2.7 144 10/25/2025
0.2.6 190 10/23/2025
0.2.5 178 10/23/2025
0.2.4 173 10/23/2025
0.2.3 185 10/23/2025
0.2.2 189 10/21/2025
0.2.1 175 10/21/2025
0.2.0 180 10/19/2025
0.1.7 187 10/19/2025
0.1.6 123 10/18/2025
0.1.5 125 10/18/2025
0.1.4 131 10/11/2025
0.1.3 126 10/11/2025
0.1.2 181 10/6/2025
0.1.1 184 10/6/2025
0.1.0 172 10/5/2025