AutoMapper and Base Types

血红的双手。 提交于 2019-12-08 08:04:06

问题


I have a collection of EntityDtos.

Each EntityDto has a property called EntityType.

Each of these EntityTypes correspond to a different subclass, something like this

abstract class EntityBase { EntityType = EntityType.Base; }
class EntityOne : EntityBase { EntityType = EntityType.One; }
class EntityTwo : EntityBase { EntityType = EntityType.Two; }

I am trying to map to a collection of EntityBase. AutoMapper fails with the error "Instances of abstract classes cannot be created". I have the Type enum, and thus know what type each should be mapped to...but really, just want them all mapped into my EntityBase collection.

I can't figure this out...

I have this working, but it's VERY ugly.

Mapper.CreateMap<EntityCollectionDto, EntityCollection>().ForMember(
    s => s.Entities, d => d.MapFrom(
        x => new List<EntityBase>(
            from p in x.Entitys
            select p.EntityType == EntityType.One ? Mapper.Map<EntityOne>(p) as EntityBase
                : p.EntityType == EntityType.Two ? Mapper.Map<EntityTwo>(p) as EntityBase
                : Mapper.Map<EntityThree>(p) as EntityBase
            )
        )
    );

 Mapper.CreateMap<EntityDto, EntityOne>();
 Mapper.CreateMap<EntityDto, EntityTwo>();

回答1:


I don't know if you'll like this any better, but assuming the entity classes as follows:

public abstract class EntityBase
{
    public EntityType EntityType { get { return EntityType.Base; } }
}
public class EntityOne : EntityBase
{
    public new EntityType EntityType { get { return EntityType.One; } }
}
public class EntityTwo : EntityBase
{
    public new EntityType EntityType { get { return EntityType.Two; } }
}
public class EntityThree : EntityBase
{
    public new EntityType EntityType { get { return EntityType.Three; } }
}
public class EntityCollection
{
    public IList<EntityBase> Entities { get; set; }
}

public class EntityDto
{
    public EntityType EntityType { get; set; }
}
public class EntityCollectionDto
{
    public IList<EntityDto> Entities { get; set; }
}

You can create a TypeConverter:

public class EntityTypeConverter : AutoMapper.TypeConverter<EntityDto, EntityBase>
{
    protected override EntityBase ConvertCore(EntityDto source)
    {
        switch (source.EntityType)
        {
            case EntityType.One:
                return AutoMapper.Mapper.Map<EntityOne>(source);
            case EntityType.Two:
                return AutoMapper.Mapper.Map<EntityTwo>(source);
            default:
                return AutoMapper.Mapper.Map<EntityThree>(source);
        }
    }
}

This will then simplify your mapping to:

AutoMapper.Mapper.CreateMap<EntityDto, EntityBase>()
    .ConvertUsing(new EntityTypeConverter());

AutoMapper.Mapper.CreateMap<EntityDto, EntityOne>();
AutoMapper.Mapper.CreateMap<EntityDto, EntityTwo>();
AutoMapper.Mapper.CreateMap<EntityDto, EntityThree>();

AutoMapper.Mapper.CreateMap<EntityCollectionDto, EntityCollection>();

AutoMapper.Mapper.AssertConfigurationIsValid();

So you still have the specific mapping in the TypeConverter (I'm not sure there's a way to avoid that), but I think the end result is a bit cleaner.



来源:https://stackoverflow.com/questions/15973258/automapper-and-base-types

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!