AutoMapper
Object-to-object mapping library for .NET — eliminates manual mapping between entity models and DTOs/view models. AutoMapper features: Profile classes defining mappings (CreateMap<Agent, AgentDto>()), auto-mapping same-named properties, custom value resolvers for computed properties, conditional mapping, flattening (Agent.User.Name → AgentDto.UserName), collection mapping (IMapper.Map<List<AgentDto>>(agents)), EF Core projection (agents.ProjectTo<AgentDto>(mapper.ConfigurationProvider) generates SELECT only mapped columns). Configuration validated at startup detecting unmapped properties. Eliminates hundreds of lines of manual property assignment in .NET agent services.
Score Breakdown
⚙ Agent Friendliness
🔒 Security
AutoMapper can inadvertently expose sensitive agent properties — CreateMap<Agent, AgentPublicDto>() maps ALL matching properties by default including ApiKey if DTO has matching property; explicitly ForMember(dest => dest.ApiKey, opt => opt.Ignore()) sensitive agent fields or use AssertConfigurationIsValid with explicit mapping per property for security-sensitive DTOs.
⚡ Reliability
Best When
Your .NET agent service maps between domain entities and multiple DTOs with many properties — AutoMapper eliminates repetitive mapping code and ProjectTo() optimizes EF Core queries.
Avoid When
You have simple few-property mappings, you need maximum mapping performance, or your team finds implicit AutoMapper conventions error-prone.
Use Cases
- • Agent entity to DTO mapping — mapper.Map<AgentDto>(agent) converts Agent domain entity to AgentDto for API response without manual property assignment; Profile defines mapping once, reused everywhere
- • EF Core query projection with AutoMapper — context.Agents.ProjectTo<AgentSummaryDto>(mapper.ConfigurationProvider).ToListAsync() generates SELECT only AgentSummaryDto properties from DB; avoids loading full Agent entity for agent list endpoints
- • Flattening nested agent objects — CreateMap<Agent, AgentDto>() with ForMember(dest => dest.OwnerEmail, opt => opt.MapFrom(src => src.Owner.Email)) flattens nested agent.Owner.Email to flat AgentDto.OwnerEmail
- • Custom agent status resolution — CreateMap<Agent, AgentDto>().ForMember(dest => dest.DisplayStatus, opt => opt.MapFrom<AgentStatusResolver>()) computes display-friendly agent status from business rules in resolver class
- • Reverse mapping for update commands — CreateMap<UpdateAgentRequest, Agent>().ReverseMap() enables both Request → Agent and Agent → Request mapping for agent update and display flows
Not For
- • Simple 1-2 property mappings — AutoMapper setup (Profile, DI registration) adds overhead; for mapping 3 properties, manual assignment is clearer; justify AutoMapper for 5+ property mappings or reuse across multiple handlers
- • Complex business logic transformations — AutoMapper resolvers can contain logic but become hard to test; for multi-step agent transformations with business rules, use explicit mapping service classes
- • Performance-critical hot paths — AutoMapper reflection-based mapping is slower than manual mapping or source generators; for agent API endpoints handling 10k+ RPS, benchmark AutoMapper vs Mapster or manual mapping
Interface
Authentication
Object mapping library — no auth concepts.
Pricing
AutoMapper is MIT licensed. Free for all use.
Agent Metadata
Known Gotchas
- ⚠ AssertConfigurationIsValid() required in tests — without validation in test suite, AutoMapper silently ignores unmapped agent properties; agent DTO missing 5 fields compiles and runs with null values; add mapper.ConfigurationIsValid() in startup or test fixture to catch mapping gaps before production
- ⚠ ProjectTo() cannot map computed properties requiring loaded navigation — ProjectTo<AgentDto>(config) translates to SQL; properties requiring C# business logic (agent.IsActive computed from multiple fields) cannot be projected; use ForMember with MapFrom(src => ...) only for SQL-translatable expressions in agent ProjectTo mappings
- ⚠ Circular reference causes infinite loop without MaxDepth — Agent.CreatedBy.CreatedAgents includes Agent causing AutoMapper infinite recursion; set MaxDepth(2) or use PreserveReferences() in CreateMap; circular agent object graphs crash mapper with StackOverflowException
- ⚠ Static IMapper is anti-pattern — early AutoMapper tutorials used static Mapper.Map(); current AutoMapper requires IMapper injected via DI; mixing static and instance mapping in agent service causes initialization order issues and breaks testability
- ⚠ Profile scanning must include all assemblies — services.AddAutoMapper(typeof(AgentProfile).Assembly) only scans that assembly; Profile classes in other agent assemblies (separate modules) are invisible; use AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies()) or list all assemblies with Profiles
- ⚠ ForMember ignore doesn't prevent exception on missing source — CreateMap<UpdateAgentRequest, Agent>().ForMember(dest => dest.Id, opt => opt.Ignore()) ignores destination Id but if source also has Id with different type, AutoMapper may still error; use ForSourceMember for source-side ignores in agent update mapping scenarios
Alternatives
Full Evaluation Report
Detailed scoring breakdown, competitive positioning, security analysis, and improvement recommendations for AutoMapper.
Scores are editorial opinions as of 2026-03-06.