AutoMapper 配置必须在启动时一次性完成,使用 Profile 类按业务域组织映射逻辑,显式注册程序集,避免运行时重复创建、空值手动判断及副作用操作,并通过 AssertConfigurationIsValid() 和 IncludeMembers 等确保映射安全。

AutoMapper 配置必须在应用启动时一次性完成,运行时重复创建 MapperConfiguration 会直接触发 AutoMapperConfigurationException,且造成内存泄漏和性能浪费。
Profile 类是组织映射逻辑的实际单位
当项目中映射关系超过 5 对,硬塞进一个匿名配置委托里就不可维护了。Profile 不是“可选技巧”,而是结构必需项——它让配置可拆分、可测试、可按模块加载。
- 每个 Profile 类必须继承
Profile,并在构造函数中调用CreateMap<TSource, TDestination>() - 推荐按业务域命名,如
UserProfile、OrderProfile,避免叫AutoMapperProfile这类泛化名 - 若 Profile 在独立类库(比如
MyApp.Application),注册时必须显式传入其程序集:AddAutoMapper(typeof(UserProfile).Assembly),否则扫描不到 - 多个 Profile 可同时注册:
AddAutoMapper(typeof(UserProfile), typeof(OrderProfile))
ForMember 中别写 null 判断或副作用逻辑
在 ForMember 的 MapFrom 委托里写 s?.Name ?? "N/A" 看似方便,实则绕过 AutoMapper 的表达式树编译优化,高频调用时 GC 压力明显上升。
- 空值替代统一用
NullSubstitute("N/A"),保留性能且语义清晰 - 需要复杂逻辑(如拼接 + 格式化 + 权限判断)?抽成
IValueResolver<TSource, TDestination, TMember>实现类,再用.ResolveUsing<MyNameResolver>() - 绝对不要在
MapFrom或ResolveUsing里查数据库、发 HTTP 请求——映射器不是执行引擎,也不该承担副作用
集合映射失败但单个对象正常?检查 CreateMap 是否已声明
_mapper.Map<List<UserDto>>(users) 返回空列表或抛异常,大概率不是语法错,而是 AutoMapper 根本没找到 CreateMap<UserEntity, UserDto>() 这条规则。
- AutoMapper 不自动推导集合映射,它只基于已注册的单类型映射来“升维”;没配单类型,集合映射就静默失效
- 确认
CreateMap<UserEntity, UserDto>()和CreateMap<UserDto, UserEntity>()是分开写的,方向反了不会报错但逻辑错乱 - 若 DTO 有只读属性(
public string Name { get; }),需额外加.ForCtorParam("name", opt => opt.MapFrom(...))或启用构造函数映射支持 - 调试时在
Program.cs最后加mapperConfiguration.AssertConfigurationIsValid();,它会立刻暴露缺失映射、类型不匹配等问题
最易被忽略的是:配置生效不等于映射安全。即使 AssertConfigurationIsValid() 通过,嵌套对象(如 User.Profile.Address.Street → UserDto.Street)仍需显式声明 IncludeMembers(x => x.Profile) 或单独配 CreateMap<Address, AddressDto>(),否则字段为 null 且无提示。


















