🎯 Complete AutoMapper Features Reference
🔧 Core Methods
| Method | Purpose | Example |
|---|---|---|
CreateMap<TSource, TDestination>() |
Defines a mapping between two types | CreateMap<User, UserDTO>(); |
Map<TDestination>(source) |
Maps source object to new destination object | var dto = _mapper.Map<UserDTO>(user); |
Map(source, destination) |
Maps source to existing destination object | _mapper.Map(updateDTO, existingUser); |
ReverseMap() |
Creates bidirectional mapping | CreateMap<User, UserDTO>().ReverseMap(); |
ForMember() |
Configures individual property mapping | .ForMember(dest => dest.FullName, opt => opt.MapFrom(...)) |
ForAllMembers() |
Applies configuration to all members | .ForAllMembers(opt => opt.Condition(...)) |
ProjectTo<TDestination>() |
Projects IQueryable to destination (EF Core) | query.ProjectTo<UserDTO>(_mapper.ConfigurationProvider) |
⚙️ ForMember Options
| Option | Purpose | Example |
|---|---|---|
MapFrom() |
Maps from a custom source expression | opt.MapFrom(src => src.FirstName + " " + src.LastName) |
MapFrom<TResolver>() |
Uses a custom value resolver | opt.MapFrom<AgeResolver>() |
Ignore() |
Ignores the destination property | opt.Ignore() |
Condition() |
Maps only if condition is true | opt.Condition(src => src.IsActive) |
NullSubstitute() |
Provides default value when source is null | opt.NullSubstitute("N/A") |
UseDestinationValue() |
Uses existing destination value instead of mapping | opt.UseDestinationValue() |
PreCondition() |
Evaluates condition before resolving | opt.PreCondition(src => src.Address != null) |
ConvertUsing() |
Uses custom conversion logic | opt.ConvertUsing(src => src.ToString()) |
📝 Profile Configuration Methods
| Method | Purpose | Example |
|---|---|---|
IncludeBase<TSource, TDest>() |
Includes base class mappings | CreateMap<Manager, ManagerDTO>().IncludeBase<Employee, EmployeeDTO>() |
IncludeMembers() |
Flattens properties from nested objects | .IncludeMembers(src => src.Address) |
BeforeMap() |
Executes logic before mapping | .BeforeMap((src, dest) => Console.WriteLine("Mapping...")) |
AfterMap() |
Executes logic after mapping | .AfterMap((src, dest) => dest.Validate()) |
ForAllOtherMembers() |
Configures unmapped members | .ForAllOtherMembers(opt => opt.Ignore()) |
ValidateMemberList() |
Validates which members are mapped | .ValidateMemberList(MemberList.Destination) |
🏷️ AutoMapper Attributes
| Attribute | Purpose | Example |
|---|---|---|
[IgnoreMap] |
Ignores property from mapping | [IgnoreMap] public string Password { get; set; } |
[SourceMember] |
Specifies source member for mapping | [SourceMember("FirstName")] public string Name { get; set; } |
Note: Attributes are less commonly used than Profile configuration. Profiles are the recommended approach as they keep mapping logic separate from domain models.
🚀 Advanced Features
1. IValueResolver
Custom resolver for complex property mapping logic:
public class AgeResolver : IValueResolver<User, UserDTO, int>
{
public int Resolve(User source, UserDTO destination, int destMember, ResolutionContext context)
{
return DateTime.Today.Year - source.DateOfBirth.Year;
}
}
2. IMemberValueResolver
More efficient when you only need source member, not entire destination:
public class CustomResolver : IMemberValueResolver<Source, Dest, SourceMember, DestMember>
{
public DestMember Resolve(Source src, Dest dest, SourceMember srcMember, DestMember destMember, ResolutionContext ctx)
{
// Logic here
}
}
3. ITypeConverter
Converts between two types globally:
public class DateTimeToStringConverter : ITypeConverter<DateTime, string>
{
public string Convert(DateTime source, string destination, ResolutionContext context)
{
return source.ToString("yyyy-MM-dd");
}
}
4. Automatic Flattening
AutoMapper automatically flattens nested properties:
// Source
public class Product {
public Category Category { get; set; }
}
public class Category {
public string Name { get; set; }
}
// Destination (automatically mapped)
public class ProductDTO {
public string CategoryName { get; set; } // Maps from Category.Name
}
5. Projection (LINQ)
Translates mappings to SQL for efficient database queries:
var userDTOs = await dbContext.Users
.Where(u => u.IsActive)
.ProjectTo<UserDTO>(_mapper.ConfigurationProvider)
.ToListAsync();
6. Collection Mapping
Automatically maps collections:
var userDTOs = _mapper.Map<List<UserDTO>>(users);
var userArray = _mapper.Map<UserDTO[]>(users);
var userEnumerable = _mapper.Map<IEnumerable<UserDTO>>(users);