如何列出应用中已配置的所有AutoMapper mapping expression trees?
解决AutoMapper循环引用导致的StackOverflow异常:如何列出所有映射表达式树
好问题!遇到循环引用引发的StackOverflow确实挺棘手的,要排查根源,第一步就是把所有已配置的AutoMapper映射都捋清楚。下面给你几个实用的方法,帮你列出所有映射及其表达式树:
1. 利用IMapper.ConfigurationProvider遍历所有映射
AutoMapper的ConfigurationProvider里存储了所有已配置的映射规则,你可以通过它直接获取所有类型映射信息,包括对应的表达式树。
示例代码:
// 假设你已经通过依赖注入或直接实例化得到了IMapper对象 var mapper = ...; // 你的IMapper实例 var configProvider = mapper.ConfigurationProvider; // 遍历所有已配置的类型映射 foreach (var typeMap in configProvider.AllTypeMaps) { Console.WriteLine($"📌 映射关系: {typeMap.SourceType.FullName} → {typeMap.DestinationType.FullName}"); Console.WriteLine("对应的表达式树结构:"); Console.WriteLine(typeMap.Expression.ToString()); Console.WriteLine("---"); }
AllTypeMaps集合包含了所有已注册的映射,每个TypeMap对象里的SourceType和DestinationType能帮你快速定位可能存在循环的类型对;typeMap.Expression就是该映射对应的表达式树,调用ToString()可以输出它的大致结构(复杂映射的输出会比较长,但足够帮你找到递归引用的线索)。
2. 在配置映射时主动记录
如果你是通过自定义Profile来配置映射,可以在添加映射时主动记录信息,方便在配置阶段就监控所有映射的创建:
示例代码:
public class CustomMappingProfile : Profile { public CustomMappingProfile() { // 添加映射并记录 var userMap = CreateMap<User, UserDto>(); Console.WriteLine($"已添加映射: {userMap.SourceType.Name} → {userMap.DestinationType.Name}"); var orderMap = CreateMap<Order, OrderDto>(); Console.WriteLine($"已添加映射: {orderMap.SourceType.Name} → {orderMap.DestinationType.Name}"); // 其他映射配置... } }
这种方式适合在开发阶段实时跟踪映射的添加,避免遗漏可能的循环配置。
3. 配合循环引用检测工具排查
找到可疑的映射后,你可以通过AutoMapper自带的配置来验证是否是循环引用导致的问题:
- 设置映射的最大深度:
CreateMap<Source, Dest>().MaxDepth(3);,限制递归次数,避免无限递归引发StackOverflow; - 启用引用保留:
CreateMap<Source, Dest>().PreserveReferences();,AutoMapper会跟踪已映射的对象,避免重复映射同一实例。
通过上面的方法,你应该能快速定位到引发循环引用的映射对,进而调整配置解决StackOverflow异常。
内容的提问来源于stack exchange,提问作者itsbpk
相关产品推荐
相关产品推荐

