如何让AutoMapper将缺失的未映射属性映射到目标对象内的字典? (与序列化期间的ExtensionData相似)
示例:
class Source
{
public int A {get;set;}
public int B {get;set;}
public int C {get;set;}
}
class Destination
{
public int A {get;set;}
public Dictionary<string, object> D {get;set;}
}
Source s = new Source { A = 1, B = 2, C = 3 };
Destination d = ... // Mapping code
现在我想要以下结果:
d.A ==> 1
d.D ==> {{ "B", 2 }, { "C", 3 }}
*编辑*
最后,我正在寻找一种没有反思的解决方案。含义:在设置/配置/初始化期间允许反射,但在映射本身期间,我不希望任何由反射引起的延迟。
*编辑*
我正在寻找一种通用解决方案,就像序列化器一样。
答案 0 :(得分:4)
您的问题有很多可能的解决方案。 我已经为您的属性创建了一个自定义值解析器,它运行正常:
public class CustomResolver : IValueResolver<Source, Destination, Dictionary<string, object>>
{
public Dictionary<string, object> Resolve(Source source, Destination destination, Dictionary<string, object> destMember, ResolutionContext context)
{
destMember = new Dictionary<string, object>();
var flags = BindingFlags.Public | BindingFlags.Instance;
var sourceProperties = typeof(Source).GetProperties(flags);
foreach (var property in sourceProperties)
{
if (typeof(Destination).GetProperty(property.Name, flags) == null)
{
destMember.Add(property.Name, property.GetValue(source));
}
}
return destMember;
}
}
如何使用它?
static void Main(string[] args)
{
Mapper.Initialize(cfg => {
cfg.CreateMap<Source, Destination>()
.ForMember(dest => dest.D, opt => opt.ResolveUsing<CustomResolver>());
});
var source = new Source { A = 1, B = 2, C = 3 };
var result = Mapper.Map<Source, Destination>(source);
}
public class Source
{
public int A { get; set; }
public int B { get; set; }
public int C { get; set; }
}
public class Destination
{
public int A { get; set; }
public Dictionary<string, object> D { get; set; }
}
答案 1 :(得分:3)
我喜欢Pawel的解决方案,因为它更通用。 如果你想要更简单但更不通用的东西,你可以像这样初始化映射器:
Mapper.Initialize(cfg => {
cfg.CreateMap<Source, Destination>()
.ForMember(dest => dest.D,
opt => opt.MapFrom(r => new Dictionary<string,object>(){{ "B", r.B},{ "C", r.C}}));
});