我正在尝试映射两个对象,并且目标具有需要额外数据源的数据。这些是课程:
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 中访问它,而无需创建解析器和/或使用反射。
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>()....
这篇文章帮助我解决了我的问题:
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");