AutoMapper stops working after moving models to another project

Viewed 31

I have an api that uses code first entity framework, and uses AutoMapper to map the entities to models before surfacing the data to the consumer. The mapping profiles exist in the same file as the respective model classes.

I'm trying to restructure the projects a bit and pull the models out into a separate project while keeping the mapping profiles where they are in the existing project. And updating the reference to point to the new project after the models are removed locally, of course. Upon doing so, AutoMapper stops working.

Before the restructure

The structure of the solution before the restructure is as follows:

Api project (Houses the controllers and api endpoints)

Startup.cs

public void ConfigureServices(IServiceCollection services) { 
    ...
    services.AddAutoMapper(typeof(LocaleModel).GetTypeInfo().Assembly)
    ...
}

Application project (Houses the MediatR handlers, models, mapping profiles, etc.)

Models/LocaleModel.cs

public class LocaleModel {
    public long Id { get; set; }
    public string Code { get; set; }
    public string Name { get; set; }
}

public class LocaleModelMapping() : Profile {
    public LocaleModelMapping() {
        CreateMap<Locale, LocaleModel>();
        CreateMap<LocaleModel, Locale>();
    }
}

Queries/Locales/Get/GetLocalesRequestHandler.cs

public async Task<IEnumerable<LocaleModel>> Handle(GetLocalesRequest request, CancellationToken cancellationToken) {
    var locales = await DbContext.Locales
       .AsNoTracking()
       .ToListAsync(cancellationToken);

    return Mapper.Map<List<LocaleModel>>(locales);
}

After the restructure

The structure of the solution after the restructure:

Api project (Houses the controllers and api endpoints)

Startup.cs

public void ConfigureServices(IServiceCollection services) { 
    ...
    services.AddAutoMapper(typeof(LocaleModelMapping).GetTypeInfo().Assembly)
    ...
}

Application project (Houses the MediatR handlers, models, mapping profiles, etc.)

Mappings/LocaleModelMapping.cs

public class LocaleModelMapping() : Profile {
    public LocaleModelMapping() {
        CreateMap<Locale, LocaleModel>();
        CreateMap<LocaleModel, Locale>();
    }
}

Models project (Houses the models only)

LocaleModel.cs

public class LocaleModel {
    public long Id { get; set; }
    public string Code { get; set; }
    public string Name { get; set; }
}

The references were updated as necessary so that the Application project is aware of the Models project.

The moment I remove the models from the Application project and refer to the Models project, AutoMapper stops working, even though I updated Startup.cs to use the assembly of a mapping profile from the Application project.

The error that is generated is as follows (full namespace censored):

Mapping types:
List`1 -> List`1
List[...Domain.Locale, ...Domain, Version=2.0.0.0] 
-> List[...Application.Models.LocaleModel, ...Application.Models, Version=1.0.0.0]
 ---> AutoMapper.AutoMapperMappingException: Missing type map configuration or unsupported mapping.

Things I've tried:

  • Putting all the mapping profiles in a single class.
  • Several different ways of passing in the assembly, types, etc. into services.AddAutoMapper().
  • Registering the mapping profiles manually in Startup.cs.
  • Mirrored another project with the same intended structure where it works just fine without issue.

Any help is appreciated!

1 Answers

Moving the Model and mapping should not have required any change to the service.AddAutomapper call beyond where the project would resolve the Assembly reference. You should have been able to leave the Startup.cs as services.AddAutoMapper(typeof(LocaleModel).GetTypeInfo().Assembly); The difference would have been the namespace where "LocaleModel" would have resolved from.

The first thing I would check is if you accidentally selected an Intellisense option to Create a new LocaleModelMapping class when you updated the Startup.cs so instead of it appending a using block to the new namespace in your Application project, it created a dummy LocaleModelMapping class somewhere in your API project leaving Automapper trying to resolve mappings from the API project still instead of the Application project. You can verify this by right clicking on the LocaleModelMapping inside (typeof(LocaleModelMapping).... and select "Go to Definition". Does this navigate you into your Application project, to an empty class in your API project, or somewhere else? (I.e. disassembly of a stale assembly reference)

Related