Sergio Romero
Sergio Romero

Reputation: 6607

Automapper: Cannot create instance of abstract type for collections

I am trying to map two entities with a many to many relationship that inherit from an abstract base class into Dtos that also inherit from their own abstract base class. When I only include the mapping for the Essay class everything works fine except that the Books collection is null, as soon as I add the mapping for that collection I get the following exception:

Inner Exception 1: ArgumentException: Cannot create an instance of abstract type Dtos.Dto`1[System.Int64].

Consider the following code:

namespace Entities
{
    public abstract class Entity<TId> : Entity
        where TId : struct, IEquatable<TId>
    {
        protected Entity()
        {
        }

        public TId Id { get; set; }
    }

    public class Essay : Entity<long>
    {
        public string Name { get; set; }
        public string Author { get; set; }

        public List<EssayBook> EssayBooks { get; set; }
    }

    public class Book : Entity<long>
    {
        public string BookName { get; set; }
        public string Publisher { get; set; }
        public List<EssayBook> EssayBooks { get; set; }
    }

    public class EssayBook
    {
        public long EssayId { get; set; }
        public long BookId { get; set; }
        public Essay Essay { get; set; }
        public Book Book { get; set; }
    }
}

namespace Dtos
{
    public abstract class Dto<TId>
       where TId : struct, IEquatable<TId>
    {
        protected Dto()
        {
        }

        public TId Id { get; set; }
    }

    public sealed class Essay : Dto<long>
    {
        public string Name { get; set; }
        public string Author { get; set; }

        public List<Book> Books { get; set; }
    }

    public class Book : Dto<long>
    {
        public string BookName { get; set; }
        public string Publisher { get; set; }
    }
}

namespace DtoMapping
{
    internal sealed class EssayBookProfile : Profile
    {
        public EssayBookProfile()
        {
            this.CreateMap<Entities.Essay, Dtos.Essay>()
                .IncludeBase<Entities.Entity<long>, Dtos.Dto<long>>()
                .ForMember(dto => dto.Books, opt => opt.MapFrom(e => e.EssayBooks.Select(pl => pl.Book)));
        }
    }
}

I've been looking to see if there is a different way to configure this mapping but I always find this way. I have also tried to specifically add the mappings for the base classes but I get the exact same result.

On my Web API project I have included the AutoMapper.Extensions.Microsoft.DependendyInjection package version 7.0.0.

Upvotes: 6

Views: 5206

Answers (1)

Sergio Romero
Sergio Romero

Reputation: 6607

As I was creating the gist by the recommendation in the post's comments I realized that the mapping for the Book dto was missing. Unfortunately the exception was not clear about the problem and that took me to ask the question here. After I added the mapping everything started working as expected.

Upvotes: 8

Related Questions