You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AutoMapper使用多个IValueResolvers时Resolve()方法的调用顺序问题

AutoMapper IValueResolver执行顺序问题解答

调用顺序异常的核心原因

AutoMapper执行映射时,成员映射的优先级和顺序不由你写ForMember的声明顺序决定,而是由目标类型(这里是Bar类)的属性获取顺序决定:

  1. 首先处理继承自父类的属性,再处理当前类声明的属性
  2. 同一层级的属性,默认顺序由.NET反射的Type.GetProperties()返回顺序决定,部分.NET版本下会按属性名字母序排序,这也是你看到AssetResolver(对应Asset属性首字母为A)最先执行的原因
  3. 你观察到剩余Resolver执行顺序和声明顺序一致,只是刚好你的Bar类中Name、HistName、Props三个属性的反射返回顺序和你写ForMember的顺序重合,属于巧合,不具备通用性

调整执行顺序的方案

  • 方案1:显式自定义类型转换器(推荐)
    如果你业务上要求多个Resolver必须按固定顺序执行,最稳妥的方式是放弃拆分多个成员级IValueResolver,改为实现ITypeConverter<Foo, Bar>,在Convert方法中按你需要的顺序显式调用各个Resolver的逻辑,示例代码如下:
    public class FooToBarConverter : ITypeConverter<Foo, Bar>
    {
        private readonly NameResolver _nameResolver;
        private readonly HistNameResolver _histNameResolver;
        private readonly AssetResolver _assetResolver;
        private readonly PropsResolver _propsResolver;
        
        // 依赖注入各个Resolver
        public FooToBarConverter(NameResolver nameResolver, HistNameResolver histNameResolver, AssetResolver assetResolver, PropsResolver propsResolver)
        {
            _nameResolver = nameResolver;
            _histNameResolver = histNameResolver;
            _assetResolver = assetResolver;
            _propsResolver = propsResolver;
        }
        
        public Bar Convert(Foo source, Bar destination, ResolutionContext context)
        {
            var dest = destination ?? new Bar();
            // 先处理普通字段映射
            dest.Id = source.ID;
            dest.ActivityName = source.Name;
            // 按你需要的顺序调用Resolver逻辑
            dest.Name = _nameResolver.Resolve(source, dest, dest.Name, context);
            dest.HistName = _histNameResolver.Resolve(source, dest, dest.HistName, context);
            dest.Asset = _assetResolver.Resolve(source, dest, dest.Asset, context);
            dest.Props = _propsResolver.Resolve(source, dest, dest.Props, context);
            return dest;
        }
    }
    
    注册映射时替换原有规则即可:
    CreateMap<Foo, Bar>().ConvertUsing<FooToBarConverter>();
    
  • 方案2:调整目标类属性声明顺序(不推荐)
    如果你使用的.NET版本下Type.GetProperties()严格按属性声明顺序返回,可以调整Bar类中属性的声明顺序,间接控制Resolver的调用顺序。但该方式依赖.NET运行时的反射实现,跨版本/跨平台可能出现异常,不建议生产环境使用。

内容的提问来源于stack exchange,提问作者Dayman75

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.20 14:45:04