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