ComnetSolution.AutoMapper 1.0.2

dotnet add package ComnetSolution.AutoMapper --version 1.0.2
                    
NuGet\Install-Package ComnetSolution.AutoMapper -Version 1.0.2
                    
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="ComnetSolution.AutoMapper" Version="1.0.2" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="ComnetSolution.AutoMapper" Version="1.0.2" />
                    
Directory.Packages.props
<PackageReference Include="ComnetSolution.AutoMapper" />
                    
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 ComnetSolution.AutoMapper --version 1.0.2
                    
#r "nuget: ComnetSolution.AutoMapper, 1.0.2"
                    
#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 ComnetSolution.AutoMapper@1.0.2
                    
#: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=ComnetSolution.AutoMapper&version=1.0.2
                    
Install as a Cake Addin
#tool nuget:?package=ComnetSolution.AutoMapper&version=1.0.2
                    
Install as a Cake Tool

ComnetSolution.AutoMapper

NuGet License: MIT .NET

A high-performance, open-source object-to-object mapper for .NET built on compiled LINQ expression trees.
Designed as a drop-in replacement for AutoMapper β€” migrate existing projects with minimal code changes.


Why ComnetSolution.AutoMapper?

AutoMapper became closed-source / commercial in recent versions. This library replicates the AutoMapper API surface you rely on β€” Profile, CreateMap, ForMember, ReverseMap, MapList, IMapper injection β€” without any licensing restrictions and with zero external dependencies beyond Microsoft.Extensions.DependencyInjection.Abstractions.

Key benefits:

  • πŸš€ Compiled expression trees β€” reflection cost paid once, subsequent maps run at near-native speed
  • πŸ” Drop-in API β€” rename AutoMapper.Profile β†’ MapperProfile, IMapper β†’ IMapper
  • πŸ”— Full DI integration β€” AddMapper(...) or auto-discover profiles with AddMapperFromAssemblies(...)
  • πŸ“¦ Multi-target β€” supports .NET 6, 7, 8 and 10
  • πŸ›‘οΈ MIT licensed β€” free for commercial and open-source use

Installation

dotnet add package ComnetSolution.AutoMapper

or via NuGet Package Manager:

Install-Package ComnetSolution.AutoMapper

Quick Start

1 β€” Define a Profile

using ComnetMapper.Configuration;

public class OrderProfile : MapperProfile
{
    public OrderProfile()
    {
        CreateMap<Order, OrderDto>()
            .ForMember(d => d.CustomerName, o => o.MapFrom(s => s.Customer.FullName))
            .ForMember(d => d.InternalNote, o => o.Ignore())   // skip this property
            .ReverseMap();                                       // also maps Dto β†’ Order
    }
}

2 β€” Register in DI (Program.cs / Startup.cs)

// Option A: list profiles explicitly
builder.Services.AddMapper(mapper =>
{
    mapper.AddProfile<OrderProfile>();
    mapper.AddProfile<CustomerProfile>();
});

// Option B: auto-discover every MapperProfile in the assembly
builder.Services.AddMapperFromAssemblies(typeof(Program).Assembly);

3 β€” Inject and Use

public class OrderService(IMapper mapper)
{
    public OrderDto GetOrder(int id)
    {
        var order = _repo.FindById(id);
        return mapper.Map<OrderDto>(order);   // single object
    }

    public List<OrderDto> GetAll()
    {
        var orders = _repo.GetAll();
        return mapper.MapList<Order, OrderDto>(orders).ToList();
    }
}

API Reference

MapperProfile

Method Description
CreateMap<TSource, TDest>() Registers a source→destination mapping
.ForMember(d => d.Prop, o => o.MapFrom(...)) Custom source expression for a member
.ForMember(d => d.Prop, o => o.Ignore()) Exclude a destination member from mapping
.BeforeMap((src, dest, mapper) => ...) Action to run before property assignment
.AfterMap((src, dest, mapper) => ...) Action to run after property assignment
.ReverseMap() Also registers the inverse (TDest β†’ TSource) map

IMapper

Method Description
Map<TDest>(object source) Map to a new TDest instance
Map<TSource, TDest>(source, destination) Map onto an existing TDest instance
MapList<TSource, TDest>(IEnumerable<TSource>) Map a collection
TryMap<TDest>(source, out MapResult<TDest>) Safe mapping β€” returns false + error instead of throwing

DI Registration

Extension Description
AddMapper(Action<Mapper>) Manual profile registration
AddMapperFromAssemblies(params Assembly[]) Auto-discover all profiles in assemblies

Advanced Examples

Before/After Map Hooks

CreateMap<User, UserDto>()
    .BeforeMap((src, dest, mapper) =>
    {
        // Runs before any property is set β€” useful for validation
        if (src.IsDeleted) throw new InvalidOperationException("Cannot map deleted user");
    })
    .AfterMap((src, dest, mapper) =>
    {
        // Runs after all properties β€” useful for computed values
        dest.DisplayName = $"{dest.FirstName} {dest.LastName}".Trim();
    });

Safe Mapping with TryMap

if (mapper.TryMap<OrderDto>(order, out var result))
{
    return result.Value;
}
else
{
    _logger.LogError("Mapping failed: {Error}", result.Error);
    return null;
}

Auto-Discover Profiles

// Scans the entire application assembly for MapperProfile subclasses
builder.Services.AddMapperFromAssemblies(
    typeof(Program).Assembly,
    typeof(SharedProfile).Assembly   // include other assemblies if needed
);

Reverse Map

CreateMap<CreateOrderRequest, Order>().ReverseMap();

// Now both directions work:
var order = mapper.Map<Order>(request);
var request = mapper.Map<CreateOrderRequest>(order);

Migration from AutoMapper

AutoMapper ComnetMapper
using AutoMapper; using ComnetMapper.Configuration;
Profile MapperProfile
IMapper IMapper
services.AddAutoMapper(...) services.AddMapper(...)
mapper.Map<TDest>(source) βœ… same
mapper.Map<TSource, TDest>(source, dest) βœ… same
CreateMap<A, B>() βœ… same
ForMember(d => d.X, o => o.MapFrom(...)) βœ… same
ForMember(d => d.X, o => o.Ignore()) βœ… same
.ReverseMap() βœ… same

Supported Type Conversions

The mapper handles the following automatically (no configuration needed):

  • Same-type assignment
  • Widening: T β†’ T? (e.g. int β†’ int?)
  • Narrowing: T? β†’ T (returns default when null)
  • Numeric conversions (int β†’ long, float β†’ double, etc.)
  • Enum ↔ enum, enum ↔ numeric
  • Implicit / explicit conversion operators
  • IEnumerable<TSrc> β†’ IList<TDest> (element-wise mapping)
  • Nested complex objects (recursively mapped)

Project Structure

ComnetMapper/
β”œβ”€β”€ src/
β”‚   └── ComnetMapper/
β”‚       β”œβ”€β”€ Abstractions/
β”‚       β”‚   └── IMapper.cs          # Public interface + MapResult<T>
β”‚       β”œβ”€β”€ Configuration/
β”‚       β”‚   └── MapperProfile.cs          # Profile base class + fluent API
β”‚       β”œβ”€β”€ Core/
β”‚       β”‚   └── Mapper.cs           # Engine: expression compilation + caching
β”‚       β”œβ”€β”€ Extensions/
β”‚       β”‚   └── MapperServiceExtensions.cs  # IServiceCollection extensions
β”‚       β”‚   └── MapperExtensions.cs  # for common methods.
β”‚       └── ComnetMapper.csproj
β”œβ”€β”€ README.md
└── LICENSE

Contributing

Contributions are welcome! Please open an issue or pull request on GitHub.

  1. Fork the repo
  2. Create a feature branch: git checkout -b feature/your-feature
  3. Commit your changes and push
  4. Open a pull request against main

License

MIT β€” see LICENSE for full text.

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 is compatible.  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 is compatible.  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.

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.2 114 4/29/2026
1.0.1 113 4/14/2026
1.0.0 99 4/14/2026