Base solution for your next web application
Open Closed

Custom mapping with Automapper #1174


User avatar
0
gpcaretti created

I am newbie of ASP.NET BoilerPlate (ABP) and I am trying to understand how to create custom mappings using AutoMapper.

if I have two classes like the following where I want the property AB to be automapped as a join of A and B:

[AutoMapTo(typeof(DestClass)]  // <= do I need it for this case?
public class SourceClass {
    public string A { get; set; }
    public string B { get; set; }
}

public class DestClass {
    public string AB { get; set; }
}

I image I have to init automapper properly by using this kind of code:

Mapper.CreateMap<SourceClass, DestClass>()
    .ForMember(dest => dest.AB,
        opts => opts.MapFrom(src => (src.A + ", " + src.B)));

My question is: As I am in my web module and the classes are used by my AppService, where do I place the automapper init code above? Also, do I need to decorate the classes with the [AutoMap] attrib (I think, no)?

Thank you


1 Answer(s)
  • User Avatar
    0
    gpcaretti created

    I try to reply by myself hoping some feedback about my solution.

    1. In MyProject.Application project I injected my Automapper custom maps by registering my mapperConfiguration. Note that I directly used the Castle IOC register methods because I did not find any useful registering method for objects in ABP.
    [DependsOn(typeof(MyProjectCoreModule), typeof(AbpAutoMapperModule))]
        public class MyProjectApplicationModule : AbpModule
        {
            public override void Initialize()
            {
                IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly());
    
                // --- MY CODE
                var mapperConfiguration = new MapperConfiguration(cfg => {
                    cfg.AddProfile(new MyProjectMapperProfile());  // <= here my custom mapping
                });
    
                var mapper = mapperConfiguration.CreateMapper();
                IocManager.IocContainer.Register(
                        Castle.MicroKernel.Registration.Component.For<IMapper>().Instance(mapper)
                    );
                // --- MY CODE
            }
        }
    
    1. I used my mapper as injection in my Application Service:
    public class UserAppService : MyNewHouseAppServiceBase, IUserAppService {
            . . .
    
            public UserAppService(IRepository<User, long> userRepository, AutoMapper.IMapper mapper) {
                . . .
            }
    
    
            public async Task<ListResultOutput<UserListDto>> GetUsers() {
                    var users = await _userRepository.GetAllListAsync();
    
                    return new ListResultOutput<UserListDto>(
                                   // USE THE INJECTED MAPPER
                                    _mapper.Map<List<UserListDto>>(users)
                                );
            }
       }
    

    What do you think about this solution?

    Tnx gp