Home > database >  Automapper: Avoid mapping source members without destination member to its abstract base class
Automapper: Avoid mapping source members without destination member to its abstract base class

Time:04-20

Question: I have two classes (source and destination) with dto's which inherit from a abstract base class. When I try to map a list with source members to the destination dto's AutoMapper tries to map the missing mapping relation ship to the abstract destination class. How can I avoid this problem?

Information: It's not possible to make sure that all source members have their destination "partner".

These are the source member classes:

namespace Source
{
   public abstract class Item
   {
       public int Id { get; set; }
       public int Size { get; set; }
       public string Name { get; set; }
       public string Description { get; set; }
   }
   public class Asset1 : Item{}
   public class Asset2 : Item{}
}

These are the destination member classes:

namespace Destination
{
   public abstract class ItemDto
   {
       public int ProductId { get; set; }
       public int Size { get; set; }
       public string ProductName { get; set; }
       public string Description { get; set; }
   }
   public class Asset1Dto : ItemDto{}
}

This is the AutoMapper Configuration:

 namespace AutoMapper
 {
   public class MappingProfile : Profile
   {
       public MappingProfile()
       {
          CreateMap<Item, ItemDto>(MemberList.Destination)
               .Include<Asset1, Asset1Dto>()
               .ForMember(o => o.ProductId, ex => ex.MapFrom(o => o.Id))
               .ForMember(o => o.ProductName, ex => ex.MapFrom(o => o.Name))
               .ReverseMap();

           CreateMap<Asset1, Asset1Dto>(MemberList.Destination).ReverseMap();            
       }
    }
 }

This is the Main-Class:

namespace AutoMapperExample
{
   public class Program
   {
       private static IList<Item> _items;
       private static IMapper _mapper;


       private static void Config()
       {
           _items = new List<Item>();
           var config = new MapperConfiguration(cfg =>
           {
               cfg.AddProfile<MappingProfile>();
           });
           _mapper = new Mapper(config);
       }

       public static void Main(string[] args)
       {
           Config();

           // Create dummy content
           var rnd = new Random().Next();

           _items.Add(new Asset1()
           {
               Name = typeof(Asset1).ToString(),
               Id = rnd,
               Size = 23,
               Description = "Dummy-Text 1"
           });

           // working case
           Console.WriteLine("Working when relation is present:");
           try
           {
               var itemDto = _mapper.Map<IList<ItemDto>>(_items);
               var jsonString = JsonSerializer.Serialize(itemDto);
               Console.WriteLine(jsonString);
           }
           catch (Exception e)
           {
               Console.WriteLine(e);
               throw;
           }
           Console.WriteLine();

           rnd = new Random().Next();
           _items.Add(new Asset2()
           {
               Name = typeof(Asset2).ToString(),
               Id = rnd,
               Size = 23,
               Description = "Dummy-Text 2"
           });

           // case which throws the exception
           Console.WriteLine("No destination member present:");
           try
           {
              var itemDto = _mapper.Map<IList<ItemDto>>(_items);
           }
           catch (Exception e)
           {
               Console.WriteLine(e);
           }
       }
   }

}

Exception I get:

---> System.ArgumentException: Cannot create an instance of abstract type ItemDto

Here is a enter image description here

  • Related