Search code examples
c#automapperobject-object-mappingautomapper-11

Use AutoMapper inside a class library project in ASP.NET Core Web API


I'm getting this error:

AutoMapper.AutoMapperMappingException: 'Missing type map configuration or unsupported mapping.'

in my project when trying to map an EF model to my DTO.

Profiles and value resolvers are in my class library project.

This is one of my profile classes:

public class InteractionGroupProfile : Profile
{
    public InteractionGroupProfile()
    {
        CreateMap<InteractionGroup, InteractionGroupDTO>()
            .ForMember(dest => dest.Employees, opt => opt.MapFrom<InteractionGroupEmployeeValueResolver>());
    }
}

And this is my value resolver:

public class InteractionGroupEmployeeValueResolver : IValueResolver<InteractionGroup, InteractionGroupDTO, List<EmployeeDTO>>
{
    private readonly Appraisal360DBContext dBContext;
    private readonly IMapper mapper;

    public InteractionGroupEmployeeValueResolver(Appraisal360DBContext dBContext, IMapper mapper)
    {
        this.dBContext = dBContext;
        this.mapper = mapper;
    }

    public List<EmployeeDTO> Resolve(InteractionGroup source, InteractionGroupDTO destination, List<EmployeeDTO> destMember, ResolutionContext context)
    {
        // Omitted for clarity
        employees.ForEach(e =>
        {
            var dto = mapper.Map<EmployeeDTO>(e);
            employeeDtos.Add(dto);
        });

        List<EmployeeDTO> employeeDtos = new List<EmployeeDTO>();

        return employeeDtos;
    }
}

As you can see, I have to inject my dbContext and IMapper into my value resolver because I need to read data from database and do a mapping inside my value resolver.

Then I just simply inject IMapper into my classes and try to use it:

public class InteractionGroupQueryFacade : IInteractionGroupQueryFacade
{
    private readonly Appraisal360DBContext context;
    private readonly IMapper mapper;

    public InteractionGroupQueryFacade(Appraisal360DBContext context, IMapper mapper)
    {
        this.context = context;
        this.mapper = mapper;
    }

    public InteractionGroupDTO GetById(Guid id)
    {
        var interactionGroup = context.InteractionGroups
            .AsNoTracking()
            .First(x => x.Id == id);

        var dto = mapper.Map<InteractionGroupDTO>(interactionGroup);

        return dto;
    }
}

This is my program.cs file where I add AutoMapper to my services:

services.AddAutoMapper(typeof(Program).Assembly,typeof(AppraisalProfile).Assembly);

My class library project is referenced by my API project as well.

Now when I run my app and try to call the GetById method in my controller, I get this error:

AutoMapper.AutoMapperMappingException: 'Missing type map configuration or unsupported mapping.'

How should I make AutoMapper recognise my profiles and value resolvers?

What is wrong with my code?

I also read this post in here and did it but it didn't help me.

Thank you.


Solution

  • If your Profile implementations are in another assembly, you need to add it during your service configuration as well.

    If I remember correctly the syntax should be:

    services.AddAutoMapper(typeof(Program), typeof(AClassOfMyLibrary));
    

    Edit:

    Yes, according to the docs, the syntx is correct:

    https://github.com/AutoMapper/AutoMapper.Extensions.Microsoft.DependencyInjection

    Scans assemblies and:

    adds profiles to mapping configuration adds value resolvers, member value resolvers, type converters to the container. To use, with an IServiceCollection instance and one or more assemblies:

    services.AddAutoMapper(assembly1, assembly2 /*, ...*/);
    

    or marker types:

    services.AddAutoMapper(type1, type2 /*, ...*/);