2010-04-20 4 views
3

J'ai un problème AutoMapper qui me rend fou depuis trop longtemps maintenant. Une question similaire a également été postée sur le site de l'utilisateur AutoMapper mais n'a pas eu beaucoup d'amour.AutoMapper ne fonctionne pas pour une classe Container

Le résumé est que j'ai une classe de conteneur qui contient un dictionnaire de composants. Les composants sont un objet dérivé d'une classe de base commune. J'ai aussi une structure parallèle que j'utilise en tant qu'objets DTO auxquels je veux mapper. L'erreur générée semble indiquer que le mappeur ne peut pas mapper entre deux des classes que j'ai incluses dans les appels CreateMap. Je pense que l'erreur a à voir avec le fait que j'ai un dictionnaire d'objets qui ne font pas partie de la hiérarchie du conteneur.

Je m'excuse d'avance pour la longueur du code ci-dessous. Mes cas de test simples fonctionnent. Inutile de dire que c'est seulement le cas le plus complexe qui échoue.

Voici les classes:

#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 

Le code:

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); 

L'erreur quand je l'appelle la carte() (rampe pile abrégée):

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) 
. 
. 

Merci à avance.

Rick

Répondre

3

Ce avéré être un bug qui a été corrigé dans la version 1.1.0.184.

Merci à Jimmy de l'avoir corrigé.

Rick