Issue
I am new of ASP.NET BoilerPlate (ABP) and I am trying to understand how to create custom mappings using AutoMapper and, maybe, the ABP automapper attributes: AutoMap, AutoMapFrom, AutoMapTo.
With ABP I can map two classes in this way:
[AutoMapTo(typeof(DestClass)]
public class SourceClass {
public string A { get; set; }
public string B { get; set; }
}
public class DestClass {
public string A { get; set; }
public string B { get; set; }
}
But 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)]
public class SourceClass {
public string A { get; set; }
public string B { get; set; }
}
public class DestClass {
public string AB { get; set; }
}
Are there some attributes with ABP? Or do I need to use the “classical” AutoMapper code:
Mapper.CreateMap<SourceClass, DestClass>()
.ForMember(dest => dest.AB,
opts => opts.MapFrom(src => (src.A + ", " + src.B)));
And where do I have to place such init code?
Solution
I found a solution I share here.
- In "MyProject.Application" project I defined my automapper customs (I used profiles):
public class MyProjectAutoMapperProfile : AutoMapper.Profile {
protected override void Configure() {
CreateMap<SourceClass, DestClass>()
.ForMember(dest => dest.AB,
opts => opts.MapFrom(src => (src.A + ", " + src.B)));
// other customs here...
}
- Then I registered it for injection in the Initialize method of the class MyProjectApplicationModule:
[DependsOn(typeof(MyProjectCoreModule), typeof(AbpAutoMapperModule))]
public class MyProjectApplicationModule : AbpModule
{
public override void Initialize()
{
IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly());
// --- MY CODE for registering custom automapping
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
}
}
Note that I directly used the Castle IOC register methods because I did not find any useful registering method for objects in ABP. Do you know one?
- Finally I used my custom mapping as injection in my Application Service and used it directly:
public class MyAppService : MyNewHouseAppServiceBase, IMyAppService {
// ...
public MyAppService(IRepository<SourceClass, long> myRepository, AutoMapper.IMapper mapper) {
_myRepo = myRepository;
_mapper = mypper;
}
public async Task<DestClass> GetSource(long id) {
var source = await _myRepo.Find(id);
// USE THE INJECTED MAPPER
return _mapper.Map<DestClass>(source);
}
public async Task<ListResultOutput<DestClass>> GetSources() {
var sources = await _myRepo.GetAllListAsync();
return new ListResultOutput<DestClass>(
// USE THE INJECTED MAPPER
_mapper.Map<List<DestClass>>(sources)
);
}
}
Answered By – Gianpiero
Answer Checked By – Mary Flores (BugsFixing Volunteer)