Basic Comparing of syntax of AutoMapper vs Mapster in solution implementing repository pattern. Link to heading
Automapper requires a class implementing abstract class Profile
and configure mappings in constructor
public class AutoMapperProfiles : Profile
{
public AutoMapperProfiles()
{
CreateMap<Photo, PhotoDto>();
}
}
Then registering this Profiles in DI container.
// Any possible, depends on requirements
services.AddAutoMapper(Assembly.GetExecutingAssembly());
services.AddAutoMapper(typeof(AutoMapperProfiles).Assembly);
Mapping Link to heading
// AutoMapper from DI
_mapper.Map<PhotoDto>(Photo)
// Mapster basic mapping like for like, no config is required.
Photo.Adapt<PhotoDto>
Complex member mappings registered in a similar way
// Automapper
public class AutoMapperProfiles : Profile
{
public AutoMapperProfiles()
{
CreateMap<AppUser, MemberDto>()
.ForMember(dest => dest.PhotoUrl,
opt => opt.MapFrom(src =>
src.Photos.FirstOrDefault(i => i.IsMain).Url))
.ForMember(dest => dest.Age, opt => opt.MapFrom(src =>
src.DateOfBirth.CalculateAge()));
}
}
// Mapster static Global settings ovverride is sufficient (DI is also possible)
var config = TypeAdapterConfig.GlobalSettings;
config.NewConfig<AppUser, MemberDto>()
.NameMatchingStrategy(NameMatchingStrategy.IgnoreCase)
.Map(dest => dest.Age,
src => src.DateOfBirth.CalculateAge())
.Map(dest => dest.PhotoUrl,
src => src.Photos.FirstOrDefault(i => i.IsMain).Url);
When dealing with EF queryable, AutoMapper requires QueryableExtensions
using AutoMapper.QueryableExtensions;
...
// Automapper requires mapper instance
_context.Users
.ProjectTo<UsersDto>(_mapper.ConfigurationProvider)
.ToListAsync();
// Maspter
_context.Users
.ProjectToType<UsersDto>()
.ToListAsync();
To make the code testable, Mapster should be injected with interface to DI container