Mapping API Reference
AutoMappic provides a fluent, type-safe API for configuring object-to-object mappings. All configurations are declared within a Profile constructor and are used by the Roslyn source generator to emit statically-optimized C# code.
1. Object Creation
ConstructUsing
Defines a custom factory for the destination type. This replaces the default constructor call in the generated code.
CreateMap<Order, OrderDto>()
.ConstructUsing(src => new OrderDto(src.OrderId, DateTime.UtcNow));2. Member Mapping
ForMember
The primary way to override default conventions for a specific destination property.
CreateMap<User, UserDto>()
.ForMember(dest => dest.FullName, opt => opt.MapFrom(src => $"{src.FirstName} {src.LastName}"));MapFrom (Custom Logic)
Redirects the source of a destination property.
- Lambda Expressions: Fully supported for direct assignments.
- Value Resolvers: Use
opt.MapFrom<TResolver>()for complex logic that requires DI services. AutoMappic generates a direct instantiation of your resolver, ensuring zero-reflection overhead.
Condition
Gates a property assignment with a predicate. If the condition is not met, the property assignment is skipped in the generated code.
CreateMap<Product, ProductDto>()
.ForMember(dest => dest.Price, opt => opt.Condition((src, dest) => src.IsVisible));Ignore
Explicitly prevents a property from being mapped. This is required for properties that have no source match to satisfy the AM0001 (Unmapped Property) diagnostic.
CreateMap<Employee, EmployeeDto>()
.ForMemberIgnore(dest => dest.InternalSecret);3. Directional Mapping
ReverseMap
Automatically generates a mapping in the opposite direction (TDestination -> TSource). You can continue the fluent chain to add specific overrides for the reverse direction.
CreateMap<User, UserDto>()
.ReverseMap()
.ForMember(src => src.InternalId, opt => opt.Ignore());4. Lifecycle Hooks
BeforeMap / AfterMap
Executes custom logic before or after the property assignment phase.
- Synchronous:
.BeforeMap((src, dest) => ...) - Asynchronous:
.BeforeMapAsync(async (src, dest) => ...) - Interceptors: When using these hooks, AutoMappic generates an internal wrapper to ensure they are executed in the correct sequence within the intercepted call.
5. Projections and Collections
Zero-LINQ Collections
AutoMappic automatically handles List<T>, T[], and IEnumerable<T> using specialized generators:
- Loop Emission: Emits a standard
forloop (orforeachfor iterables) instead of calling LINQ methods. - Pre-allocation: Uses
new List<T>(count)ornew T[count]to optimize memory pressure when the source size is known at runtime.
ProjectTo (EF Core)
Converts an IQueryable<T> into an IQueryable<U> at compile-time.
// Recommended: Simplified extension method
var dtos = dbContext.Users.ProjectTo<UserDto>().ToList();
// Or legacy compatibility signature
var dtos = dbContext.Users.ProjectTo<UserDto>(_mapper.ConfigurationProvider).ToList();DataReader.Map
High-performance, non-reflective projection from an ADO.NET IDataReader.
using var reader = cmd.ExecuteReader();
var users = reader.Map<UserDto>();DataReader.MapAsync (v0.7.0 "The Ultimate" Streaming)
Stream millions of rows directly into your logic with zero allocation using IAsyncEnumerable<T>.
using var reader = await cmd.ExecuteReaderAsync();
await foreach (var user in reader.MapAsync<UserDto>())
{
// Process user without loading the entire result set in memory!
}6. Standalone Mappings ([AutoMap])
AutoMappic v0.6.0 allows you to define mappings directly on your DTO classes, eliminating the need for a separate Profile class for simple scenarios.
using AutoMappic;
[AutoMap(typeof(UserSource), ReverseMap = true)]
public partial class UserDto
{
public int Id { get; set; }
public string Name { get; set; }
}TIP
Standalone mapping classes must be marked as partial so the generator can inject optimized mapping interfaces.
7. Advanced v0.6.0 Features
AutoMappic v0.6.0 introduces state-aware mapping and hardened projection support for complex scenarios.
Identity Management
Ensures that the same source object instance is always mapped to the same destination instance within a single mapping tree, preventing infinite recursion in cyclic models.
public class MyProfile : Profile
{
public MyProfile()
{
// Globally enable for this profile
EnableIdentityManagement = true;
CreateMap<Category, CategoryDto>();
}
}Entity Smart-Sync (Match-and-Update)
When mapping to an existing collection on a destination entity, AutoMappic matches items by their Primary Key (Id or [AutoMappicKey]).
- Match Found: Updates the existing instance in-place (preserving EF Core Change Tracker state).
- No Match: Adds a new instance to the collection.
- Removed: Removes the instance from the collection.
public class OrderProfile : Profile
{
public OrderProfile()
{
// Enable differential collection syncing
EnableEntitySync = true;
CreateMap<Order, OrderEntity>();
}
}8. Choosing Your Mapping Path
AutoMappic offers two ways to invoke generated code. Understanding the difference is key to long-term architectural success.
Path A: Classic Interception (Standard)
This is the default path. You use the standard IMapper interface exactly like you would with legacy mapping solutions.
using AutoMappic;
// ...
var dto = mapper.Map<User, UserDto>(source);- How it works: At compile-time, a Roslyn Interceptor diverts this call to a highly optimized static method.
- Namespace Required:
using AutoMappic; - Benefit: 100% syntactical compatibility with existing codebases. No changes required to your business logic.
Path B: Fluent Pattern (v0.7.0 Recommended)
For a more modern, object-oriented approach, you can call the generated code directly as an extension method on your source object while passing the mapper instance.
using AutoMappic;
// ...
var dto = source.MapTo<UserDto>(mapper);- How it works: A generic extension method intercepts the
MapTo<TDest>call just like standard mapping. - Namespace Required:
using AutoMappic; - Benefit: Elegant syntax that plays beautifully with LINQ (
.Select(x => x.MapTo<Dest>(mapper))) and retains full static interception and AOT-safety without interface dispatch overhead.