在 .ForMember() 中访问 IMappingOperationOptions 字典,无需 IValueResolver

问题描述 投票:0回答:2

我正在尝试映射两个对象,并且目标具有需要额外数据源的数据。这些是课程:

public class SourceClass {
  public int SrcValueOne { get; set; }
}

public class DestClass { 
  public int DestValueOne { get; set; }

  public int ValueFromConfig { get; set; }
}

public class ConfigSettings { 
  public int ConfigValueOne { get; set; }
}

我需要将 SourceClass 中的值映射到 DestClass,同时将填充的 ConfigSettings 对象(在运行时)传递到 Map() 并从那里读取一些值。到目前为止,我发现的只是一种看起来并不理想的

ResolveUsing
方法。我想知道是否有办法做类似的事情:

Mapper.CreateMap<SourceClass, DestClass>()
  .ForMember(dest => dest.DestValueOne, src => src.MapFrom(a => a.SrcValueOne))
  .ForMember(dest => dest.ValueFromConfig, src => opt.ResolveUsing<ConfigSettings>.FromMember(config => config.ConfigValueOne);

我弄清楚了如何在运行时使用 Items 集合在

Map()
中传递填充的对象,但无法弄清楚是否有办法在 ResolveUsing 中访问它,而无需创建解析器和/或使用反射。

.net automapper
2个回答
1
投票
Mapper.CreateMap<ConfigSettings, DestCLass>() .ForMember(dest => dest.ValueFromConfig, opt => opt.MapFrom(s => s.ConfigValueOne)) .ForMember(dest => dest.DestValueOne, opt => opt.Ignore()); Mapper.CreateMap<SourceClass, DestClass>() .ForMember(dest => dest.DestValueOne, opt => opt.MapFrom(a => a.SrcValueOne)) .ForMember(dest => dest.ValueFromConfig, opt => opt.Ignore()); var dest = Mapper.Map(config); Mapper.Map(source, dest);

如果您不想引入另一个类,这是最简单的选择。

添加一个新类有助于将其封装为仅一个 Map 调用:

public class ComplexSource { public ConfigSettings Config{get;set;} public SourceClass SourceData{get;set;} } Mapper.CreateMap<ComplexSource, DestClass>()....
    

0
投票
我有一个类似的问题 - 目标类中的属性仅在映射时才知道。

这篇文章帮助我解决了我的问题:

https://www.codeproject.com/Tips/5320490/AutoMapper-Runtime-Mapping-Control-via

有两节课:

public class TrackDto { public long StateId { get; set; } public Guid TrackId { get; set; } } public record Track { public string CameraName { get; init; } // to be set in runtime public Guid TrackId { get; init; } public long StateId { get; init; } }
我最终得到了以下映射:

var config = new MapperConfiguration(cfg => { cfg.CreateMap<TrackDto, Track>() .ForMember(d => d.CameraName, opt => opt.MapFrom( (dto, track, obj, ctx) => (string)ctx.Items[nameof(Track.CameraName)])); }); var mapper = config.CreateMapper(); var dto = new TrackDto { StateId = 2, TrackId = Guid.NewGuid(), }; var tr = mapper.Map<Track>(dto, opt => opt.Items[nameof(Track.CameraName)] = "cam1");
    
© www.soinside.com 2019 - 2024. All rights reserved.