2012-09-21 82 views
1

我试图将我的DTO对象映射到工厂类中的实体对象。 DTO具有所有字段值,而实体具有由名称和值组成的字段。Automapper实例化目标对象而不是递归映射

经过一些调试,我发现Automapper实例化每个实体字段,而不是使用现有的字段。结果,最后一次测试失败。

[TestFixture] 
class RecursiveMappingTest 
{ 
    public class SourceInfo 
    { 
     public string Info1 = "info1"; 
     public string Info2 = "info1"; 
    } 

    public class StringField 
    { 
     public string Name; 
     public string Value; 
    } 

    public class DestinationInfo 
    { 
     public StringField Info1 = new StringField() { Name = "field name 1" }; 
     public StringField Info2 = new StringField() { Name = "field name 2" }; 
    } 

    [Test] 
    public void MapField() 
    { 
     Mapper.CreateMap<string, StringField>() 
      .ForMember(dest => dest.Value, opt => opt.MapFrom(src => src)); 

     Mapper.CreateMap<SourceInfo, DestinationInfo>(); 

     SourceInfo sourceInfo = new SourceInfo(); 
     DestinationInfo destinationInfo = new DestinationInfo(); 

     Mapper.Map(sourceInfo, destinationInfo); 

     // these pass 
     Assert.That(destinationInfo.Info1.Value, Is.EqualTo("info1")); 
     Assert.That(destinationInfo.Info2.Value, Is.EqualTo("info1")); 

     // this fails since automapper instantiated brand new StringField() 
     // which has Name == "". 
     Assert.That(destinationInfo.Info1.Name, Is.EqualTo("field name 1")); 
    } 
} 

这是预期的行为吗?我怎样才能达到我想要的?实体类中有很多字段,所以this workaround will not work for me

+0

我结束了使用[ValueInjector](http://valueinjecter.codeplex.com/)来解决这个问题。它还解决了一旦这个问题得到解决,我必须经历的其他Automapper挑战。 ValueInjector没有任何魔力,但一切都是透明的 - 或者我应该说简单的结构真的是魔术 - 源代码很容易掌握并学习如何制作自定义的注入代码。因为我很好奇在Automapper中知道这个特殊问题,所以我会留下这个问题。 – kennethc

+0

如果实体中的字段数量是问题,则可以始终使用t4模板。 –

回答

1

试着改变你的第二个地图:

Mapper.CreateMap<SourceInfo, DestinationInfo>() 
.ForAllMembers(x => x.UseDestinationValue()); 

这应该使用的目标值,将所有未映射的属性。

+0

Mapper.AssertConfigurationIsValid()失败,但它适用于我,因为我有不同的方法来检查一切是否映射良好。谢谢虚空光芒! – kennethc

+0

我发现了另一个问题。奇怪的,但如果我改变的价值是相同的(像都是'“info1”')我得到一个错误,说'System.ArgumentException:具有相同的密钥项目已被添加.'我改变了问题反映问题。 – kennethc