简体   繁体   中英

Automapper mapping with IncludeBase failing for abstract generic class

I am trying to map reference data entities to dtos, both of which inherit from a generic base class within their own namespace and using an "all purpose" profile to add the mappings. Consider the following code:

namespace Dtos
{
    public abstract class ReferenceData<TId>
        where TId : Enum
    {
        public TId Id { get; set; }

        public string Description { get; set; }
    }

    public class ConcreteDto : ReferenceData<MyEnum> { }
}

namespace Entities
{
    public abstract class ReferenceData<TId>
        where TId : Enum
    {
        public TId Id { get; set; }

        public string Description { get; set; }
    }

    public class ConcreteEntity : ReferenceData<MyEnum> { }
}

namespace DtoMapping
{
    internal abstract class ReferenceDataDtoProfile<TDto, TEntity, TId> : Profile
    where TDto : Dtos.ReferenceData<TId>
    where TEntity : Entities.ReferenceData<TId>
    where TId : Enum
    {
        public ReferenceDataDtoProfile()
        {
        }

        protected IMappingExpression<TDto, TEntity> CreateDtoToEntityMap()
        {
            return this.CreateMap<TDto, TEntity>()
                        .IncludeBase<Dtos.ReferenceData<TId>, Entities.ReferenceData<TId>>();
        }

        protected IMappingExpression<TEntity, TDto> CreateEntityToDtoMap()
        {
            return this.CreateMap<TEntity, TDto>()
                        .IncludeBase<Entities.ReferenceData<TId>, Dtos.ReferenceData<TId>>();
        }

        protected void CreateMaps()
        {
            this.CreateDtoToEntityMap();
            this.CreateEntityToDtoMap();
        }
    }

    internal sealed class ProfileForConcreteEntity : ReferenceDataDtoProfile<Dtos.ConcreteDto, Entities.ConcreteEntity, MyEnum>
    {
        public PeriodProfile()
        {
            this.CreateMaps();
        }
    }   
}

When I run the application and try to get to the endpoint in question I can see in the debugger that the code of the ReferenceDataDtoProfile class gets executed but then I get the exception that there are no mappings for this objects, specifically:

InvalidOperationException: Missing map from Dtos.ReferenceData'1[MyEnum] to Entities.ReferenceData'1[MyEnum]. Create using CreateMap(ReferenceData'1, ReferenceData'1).

As you can see I am adding the "IncludeBase" method for both ReferenceData abstract classes so I do not understand why I am getting this exception.

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

Thank you.

It appears that IncludeBase just specifies that the mapping of the derived objects will inherit the configuration of the base objects. However, you still need to create the actual mapping for both the base and derived objects:

protected IMappingExpression<TDto, TEntity> CreateDtoToEntityMap() 
{ 
    this.CreateMap<Dtos.ReferenceData<TId>, Entities.ReferenceData<TId>>();
    return this.CreateMap<TDto, TEntity>() 
        .IncludeBase<Dtos.ReferenceData<TId>, Entities.ReferenceData<TId>>(); 
} 

protected IMappingExpression<TEntity, TDto> CreateEntityToDtoMap() 
{
    this.CreateMap<Entities.ReferenceData<TId>, Dtos.ReferenceData<TId>>();
    return this.CreateMap<TEntity, TDto>() 
        .IncludeBase<Entities.ReferenceData<TId>, Dtos.ReferenceData<TId>>(); 
}

See Mapping Inheritance for more info.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM