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

如何配置AutoMapper复用基类映射,避免依赖静态实例?

优化AutoMapper映射配置(依赖注入场景)

针对你遇到的依赖注入下复用基类映射、避免静态Mapper的问题,这里有两种优雅的解决方案,都能让你摆脱静态实例依赖,同时减少冗余代码:

方案1:改进AfterMap使用ResolutionContext

这是对现有代码的最小改动,只需要修改AfterMap的参数,利用AutoMapper提供的ResolutionContext获取当前的IMapper实例,完全避免静态依赖:

public class YourMappingProfile : Profile
{
    public YourMappingProfile()
    {
        // 先配置公共基类映射
        CreateMap<AnotherModel, Model>();

        // EFObject → AModel 映射:复用基类映射 + 配置特有属性
        CreateMap<EFObject, AModel>()
            .ForMember(dest => dest.AModelId, opt => opt.MapFrom(src => src.Id))
            // 使用上下文里的Mapper实例,替代静态Mapper
            .AfterMap((src, dest, context) => context.Mapper.Map(src.AnotherModel, dest))
            .ReverseMap();

        // 同理配置 EFObject → BModel
        CreateMap<EFObject, BModel>()
            .ForMember(dest => dest.BModelId, opt => opt.MapFrom(src => src.Id))
            .AfterMap((src, dest, context) => context.Mapper.Map(src.AnotherModel, dest))
            .ReverseMap();
    }
}

优势:

  • 几乎不需要调整现有映射结构,改造成本低
  • ResolutionContext.Mapper是当前注入的实例,完美适配依赖注入和单元测试场景

方案2:声明式复用基类映射(推荐)

这种方案更符合AutoMapper的设计理念,用声明式配置替代命令式的AfterMap,代码更清晰易维护:

public class YourMappingProfile : Profile
{
    public YourMappingProfile()
    {
        // 1. 公共基类映射
        CreateMap<AnotherModel, Model>();

        // 2. 配置 EFObject → Model 的映射,复用上面的基类映射
        CreateMap<EFObject, Model>()
            .ConvertUsing((src, _, context) => context.Mapper.Map<AnotherModel, Model>(src.AnotherModel));

        // 3. EFObject → AModel:继承基类映射 + 配置特有属性
        CreateMap<EFObject, AModel>()
            .IncludeBase<EFObject, Model>()
            .ForMember(dest => dest.AModelId, opt => opt.MapFrom(src => src.Id))
            .ReverseMap();

        // 4. EFObject → BModel 同理
        CreateMap<EFObject, BModel>()
            .IncludeBase<EFObject, Model>()
            .ForMember(dest => dest.BModelId, opt => opt.MapFrom(src => src.Id))
            .ReverseMap();
    }
}

优势:

  • 完全遵循AutoMapper的声明式配置原则,可读性和可维护性更强
  • 逻辑分层清晰:基类映射、EF到基类的转换、子类特有属性配置

单元测试示例(两种方案通用)

现在不需要初始化静态Mapper,只需要创建局部的IMapper实例即可完成测试:

[Test]
public void EFObject_To_AModel_Maps_Correctly()
{
    // 构建Mapper配置
    var config = new MapperConfiguration(cfg => cfg.AddProfile<YourMappingProfile>());
    var mapper = config.CreateMapper();

    // 准备测试数据
    var testEfObject = new EFObject
    {
        Id = 123,
        NestedId = 456,
        AnotherModel = new AnotherModel { /* 填充基类属性 */ }
    };

    // 执行映射
    var result = mapper.Map<AModel>(testEfObject);

    // 验证结果
    Assert.AreEqual(testEfObject.Id, result.AModelId);
    // 验证基类属性映射是否正确
    Assert.AreEqual(testEfObject.AnotherModel.BasePropertyX, result.BasePropertyX);
}

这样你的单元测试就能独立运行,完全不依赖全局静态实例。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:17:11