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

如何使用AutoMapper实现动态映射?

解决AutoMapper动态映射外部类型的问题

问题分析

你遇到的错误根源有两个:

  1. 泛型CreateMap的局限性:泛型版本CreateMap<TSource, TDest>要求目标类型TDest是编译时已知的类型,而你传入的是运行时通过反射获取的myType,不符合泛型的使用规则。
  2. ForMember表达式不合法:AutoMapper的ForMember方法需要接收能直接指向目标属性的表达式树,你用dest=> dest.GetType().GetProperties(...)这种反射动态获取属性的方式,无法被AutoMapper解析为合法的成员访问路径,导致它无法识别目标属性,从而抛出配置异常。

解决方案

利用AutoMapper的非泛型API,结合目标类型固定的命名规则(如ProductType的属性均为ProductTypeXXX格式),批量创建映射规则,无需逐个手动配置:

代码实现

using System.Linq;
using AutoMapper;

// 从外部程序集中筛选符合规则的目标类型(这里以名称以"Type"结尾为例,可根据实际调整筛选条件)
var targetTypes = Assemblies.ExportedTypes
    .Where(t => t.Name.EndsWith("Type") && t.IsClass && !t.IsAbstract);

var config = new MapperConfiguration(cfg =>
{
    foreach (var targetType in targetTypes)
    {
        // 使用非泛型CreateMap创建从TypeTableUpsert到目标类型的映射
        var mappingExpr = cfg.CreateMap(typeof(TypeTableUpsert), targetType);

        // 按命名规则匹配并配置属性映射
        // 映射TypeID → {目标类型名}ID(如ProductTypeID)
        var idPropName = $"{targetType.Name}ID";
        mappingExpr.ForMember(idPropName, opt => opt.MapFrom(src => src.TypeID));

        // 映射TypeName → {目标类型名}Name(如ProductTypeName)
        var namePropName = $"{targetType.Name}Name";
        mappingExpr.ForMember(namePropName, opt => opt.MapFrom(src => src.TypeName));

        // 映射TypeCode → {目标类型名}Code(如ProductTypeCode)
        var codePropName = $"{targetType.Name}Code";
        mappingExpr.ForMember(codePropName, opt => opt.MapFrom(src => src.TypeCode));

        // 映射TypeDescription → {目标类型名}Description(如ProductTypeDescription)
        var descPropName = $"{targetType.Name}Description";
        mappingExpr.ForMember(descPropName, opt => opt.MapFrom(src => src.TypeDescription));
    }
});

// 验证映射配置(开发环境建议启用,生产环境可注释)
config.AssertConfigurationIsValid();

// 创建Mapper实例
var mapper = config.CreateMapper();

关键说明

  1. 非泛型API适配动态类型:非泛版CreateMap直接接收Type对象,完美适配运行时动态获取的外部类型,无需编译时确定类型。
  2. 命名规则驱动映射:利用目标类型属性的固定命名规律,动态拼接属性名称并传递给ForMember,这是AutoMapper支持的合法配置方式,避免了表达式树解析失败的问题。
  3. 自动兼容新增类型:未来新增的外部类型只要符合当前命名规则,无需修改映射代码,就能自动被纳入映射配置。

映射使用示例

当需要执行映射时,使用非泛版Map方法:

// 动态获取目标类型
Type targetType = Assemblies.ExportedTypes.Single(t => t.Name == "ProductType");
// 构造DTO实例
var upsertDto = new TypeTableUpsert 
{ 
    TypeID = 1, 
    TypeName = "Test Product", 
    TypeCode = "TP001", 
    TypeDescription = "Test Description" 
};

// 执行动态映射
var targetInstance = mapper.Map(upsertDto, typeof(TypeTableUpsert), targetType);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 10:40:37