AutoMapper / AutoMapper.Extensions.Microsoft.DependencyInjection

MIT License
258 stars 79 forks source link

Error mapping types List -> List #140

Closed mc0re closed 4 years ago

mc0re commented 4 years ago

Source/destination types

Source:

    public class UserModel
    {
        public Guid Id { get; set; }

        public string UserName { get; set; }

        public string FullName { get; set; }

        public string Email { get; set; }

        public List<string> Roles { get; set; }

        public DateTime CreatedOn { get; set; }

        public List<AssignmentModel> Assignments { get; set; }
    }

Destination

    public sealed class UserDto
    {
        public Guid Id { get; set; }

        public string UserName { get; set; }

        public string FullName { get; set; }

        public string[] Roles { get; set; }
    }

Mapping configuration

Tried two variants.

  1. Automatic

    CreateMap<UserModel, UserDto>();
  2. Fully specified

    CreateMap<UserModel, UserDto>()
    .ForMember(d => d.Id, opt => opt.MapFrom(s => s.Id))
    .ForMember(d => d.UserName, opt => opt.MapFrom(s => s.UserName))
    .ForMember(d => d.FullName, opt => opt.MapFrom(s => s.FullName))
    .ForMember(d => d.Roles, opt => opt.MapFrom(s => s.Roles))
    .ForAllOtherMembers(opt => opt.Ignore())
    ;

Injection configuration:

services.AddAutoMapper(
    (provider, expr) =>
    {
        expr.ConstructServicesUsing(provider.GetService);
    },
    AppDomain.CurrentDomain.GetAssemblies());

Version: 9.0.0 and 10.0.0

Expected behavior

No error

Actual behavior

 AuthorsController_GetList
   Source: AuthorsControllerShould.cs line 44
   Duration: 8.5 sec

  Message: 
    Test method Tests.AuthorsControllerShould.AuthorsController_GetList threw exception: 
    AutoMapper.AutoMapperMappingException: Error mapping types.

    Mapping types:
    Object -> List`1
    System.Object -> System.Collections.Generic.List`1[[Dto.UserDto, Dto] 

---> AutoMapper.AutoMapperMappingException: Missing type map configuration or unsupported mapping.

    Mapping types:
    UserModel -> UserDto
    Models.UserModel -> Dto.UserDto
  Stack Trace: 
    lambda_method(Closure , UserModel , UserDto , ResolutionContext )
    lambda_method(Closure , Object , List`1 , ResolutionContext )
    --- End of inner exception stack trace ---
    lambda_method(Closure , Object , List`1 , ResolutionContext )
    AuthorsController.ListAuthors() line 63
    AuthorsControllerShould.AuthorsController_GetList() line 51
    ThreadOperations.ExecuteWithAbortSafety(Action action)

Steps to reproduce

Simple test case.

var list = new List<UserModel> { 2 users };
var res = mMapper.Map<List<UserDto>>(list);
mc0re commented 4 years ago

What's even stranger, even this profile produces the error:

public class UserDtoMappingProfile : Profile
{
    public UserDtoMappingProfile()
    {
        CreateMap<UserModel, UserDto>()
            .ForMember(d => d.Id, opt => opt.Ignore())
            .ForMember(d => d.UserName, opt => opt.Ignore())
            .ForMember(d => d.FullName, opt => opt.Ignore())
            .ForMember(d => d.Roles, opt => opt.Ignore())
            .ForAllOtherMembers(opt => opt.Ignore())
            ;
    }
}

Yes, one might think the profile is not picked up - but it is sitting side by side with other profiles, which are definitely picked up.

jbogard commented 4 years ago

Don't do that AppDomain thing - explicitly specify your assemblies.

lbargaoanu commented 4 years ago

I think this is better suited for StackOverflow.

jbogard commented 4 years ago

This is a usage problem - your DI configuration is unneeded (this is done by the AddAutoMapper method, and you shouldn't scan the AppDomain. Pass in your assemblies to scan explicitly. However, because this is a usage problem based on your exception, it's better suited for SO because that'll be better for anyone else in the future that encounters the same problem.

mc0re commented 4 years ago

Okay, for the record - I confirm that explicitly specifying assemblies fixed the issue.

github-actions[bot] commented 3 years ago

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.