2010-04-20 73 views
3

我有一个AutoMapper问题,现在已经让我疯狂得太久了。 AutoMapper用户网站也发布了类似的问题,但没有得到太多的关注。AutoMapper不适用于Container类

总结是,我有一个包含组件字典的容器类。这些组件是一个公共基类的派生对象。我也有一个平行结构,我正在使用DTO对象来映射它。

生成的错误似乎表明映射器无法在我包含在CreateMap调用中的两个类之间进行映射。我认为这个错误与我有一个不属于容器层次结构的对象字典有关。

对于下面的代码长度,我提前表示歉意。我的简单测试案例工作。不用说,这只是更复杂的失败案例。

这里是类:

#region Dto objects 

public class ComponentContainerDTO 
{ 
    public Dictionary<string, ComponentDTO> Components { get; set; } 

    public ComponentContainerDTO() 
    { 
     this.Components = new Dictionary<string, ComponentDTO>(); 
    } 
} 

public class EntityDTO : ComponentContainerDTO 
{ 
    public int Id { get; set; } 

} 

public class ComponentDTO 
{ 
    public EntityDTO Owner { get; set; } 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public string ComponentType { get; set; } 
} 

public class HealthDTO : ComponentDTO 
{ 
    public decimal CurrentHealth { get; set; } 

} 

public class PhysicalLocationDTO : ComponentDTO 
{ 
    public Point2D Location { get; set; } 
} 
#endregion 


#region Domain objects 

public class ComponentContainer 
{ 
    public Dictionary<string, Component> Components { get; set; } 

    public ComponentContainer() 
    { 
     this.Components = new Dictionary<string, Component>(); 
    } 
} 

public class Entity : ComponentContainer 
{ 
    public int Id { get; set; } 

} 

public class Component 
{ 
    public Entity Owner { get; set; } 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public string ComponentType { get; set; } 

} 

public class Health : Component 
{ 
    public decimal CurrentHealth { get; set; } 
} 

public struct Point2D 
{ 
    public decimal X; 
    public decimal Y; 

    public Point2D(decimal x, decimal y) 
    { 
     X = x; 
     Y = y; 
    } 
} 

public class PhysicalLocation : Component 
{ 
    public Point2D Location { get; set; } 
} 
#endregion 

代码:

var entity = new Entity() { Id = 1 }; 
var healthComponent = new Health() { CurrentHealth = 100, Owner = entity, Name = "Health", Id = 2 }; 
entity.Components.Add("1", healthComponent); 
var locationComponent = new PhysicalLocation() { Location = new Point2D() { X = 1, Y = 2 }, Owner = entity, Name = "PhysicalLocation", Id = 3 }; 
entity.Components.Add("2", locationComponent); 

Mapper.CreateMap<ComponentContainer, ComponentContainerDTO>() 
    .Include<Entity, EntityDTO>(); 

Mapper.CreateMap<Entity, EntityDTO>(); 

Mapper.CreateMap<Component, ComponentDTO>() 
    .Include<Health, HealthDTO>() 
    .Include<PhysicalLocation, PhysicalLocationDTO>(); 

Mapper.CreateMap<Component, ComponentDTO>(); 
Mapper.CreateMap<Health, HealthDTO>(); 
Mapper.CreateMap<PhysicalLocation, PhysicalLocationDTO>(); 

Mapper.AssertConfigurationIsValid(); 

var targetEntity = Mapper.Map<Entity, EntityDTO>(entity); 

的错误,当我调用地图()(简称堆爬):

AutoMapper.AutoMapperMappingException was unhandled 
    Message=Trying to map MapperTest1.Entity to MapperTest1.EntityDTO. 
Using mapping configuration for MapperTest1.Entity to MapperTest1.EntityDTO 
Exception of type 'AutoMapper.AutoMapperMappingException' was thrown. 
    Source=AutoMapper 
    StackTrace: 
     at AutoMapper.MappingEngine.AutoMapper.IMappingEngineRunner.Map(ResolutionContext context) 
. 
. 
. 

    InnerException: AutoMapper.AutoMapperMappingException 
     Message=Trying to map System.Collections.Generic.Dictionary`2[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[MapperTest1.Component, ElasticTest1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]] to System.Collections.Generic.Dictionary`2[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[MapperTest1.ComponentDTO, ElasticTest1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]. 
Using mapping configuration for MapperTest1.Entity to MapperTest1.EntityDTO 
Destination property: Components 
Exception of type 'AutoMapper.AutoMapperMappingException' was thrown. 
     Source=AutoMapper 
     StackTrace: 
      at AutoMapper.Mappers.TypeMapObjectMapperRegistry.PropertyMapMappingStrategy.MapPropertyValue(ResolutionContext context, IMappingEngineRunner mapper, Object mappedObject, PropertyMap propertyMap) 
. 
. 

     InnerException: AutoMapper.AutoMapperMappingException 
      Message=Trying to map System.Collections.Generic.Dictionary`2[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[MapperTest1.Component, ElasticTest1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]] to System.Collections.Generic.Dictionary`2[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[MapperTest1.ComponentDTO, ElasticTest1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]. 
Using mapping configuration for MapperTest1.Entity to MapperTest1.EntityDTO 
Destination property: Components 
Exception of type 'AutoMapper.AutoMapperMappingException' was thrown. 
      Source=AutoMapper 
      StackTrace: 
       at AutoMapper.MappingEngine.AutoMapper.IMappingEngineRunner.Map(ResolutionContext context) 
       . 
      InnerException: AutoMapper.AutoMapperMappingException 
       Message=Trying to map MapperTest1.Component to MapperTest1.ComponentDTO. 
Using mapping configuration for MapperTest1.Health to MapperTest1.HealthDTO 
Destination property: Components 
Exception of type 'AutoMapper.AutoMapperMappingException' was thrown. 
       Source=AutoMapper 
       StackTrace: 
         at AutoMapper.MappingEngine.AutoMapper.IMappingEngineRunner.Map(ResolutionContext context) 
         . 
. 

       InnerException: AutoMapper.AutoMapperMappingException 
         Message=Trying to map System.Decimal to System.Decimal. 
Using mapping configuration for MapperTest1.Health to MapperTest1.HealthDTO 
Destination property: CurrentHealth 
Exception of type 'AutoMapper.AutoMapperMappingException' was thrown. 
         Source=AutoMapper 
         StackTrace: 
          at AutoMapper.Mappers.TypeMapObjectMapperRegistry.PropertyMapMappingStrategy.MapPropertyValue(ResolutionContext context, IMappingEngineRunner mapper, Object mappedObject, PropertyMap propertyMap) 

. 
. 
         InnerException: System.InvalidCastException 
          Message=Unable to cast object of type 'MapperTest1.ComponentDTO' to type 'MapperTest1.HealthDTO'. 
          Source=Anonymously Hosted DynamicMethods Assembly 
          StackTrace: 
           at SetCurrentHealth(Object , Object) 
. 
. 

谢谢你提前。

里克

回答

3

事实证明,这是已经被固定在1.1.0.184版中的错误。

谢谢吉米修复它。

Rick