نبرد نگاشتگرها در .NET: مقایسه عمیق AutoMapper و Mapster
نویسنده: وحید نصیری
تاریخ: ۱۴۰۴/۰۶/۱۷ ۰۹:۳۶
آدرس: www.dntips.ir
| مطالب | ۳۶۹۴ |
| نویسندگان | ۲۷۶ |
| گروههای مطالب | ۱۰۲۴ |
| نقشههای راه | ۱۱۹ |
| دورهها | ۱۴ |
| اشتراکها | ۱۷۹۱۴ |
var dest = source.Adapt.User و UserDto داریم و میخواهیم مقادیر را بین آنها نگاشت کنیم.// Automapper
// 1. Define mapping configuration
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<User, UserDto>();
});
// 2. Create mapper instance
var mapper = config.CreateMapper();
// 3. Perform mapping
UserDto dto = mapper.Map<UserDto>(user);
// Mapster
// No setup required for simple mappings
UserDto dto = user.Adapt<UserDto>();ForMember و در Mapster از Map استفاده میشود. هرچند سینتکس در این بخش کمی شبیه است، اما رویکرد کلی Mapster برای پیکربندیهای سفارشی نیز همچنان سبک و ساده است.// AutoMapper
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<User, UserDto>()
.ForMember(dest => dest.FullName,
opt => opt.MapFrom(src => src.FirstName + " " + src.LastName));
});
var mapper = config.CreateMapper();
UserDto dto = mapper.Map<UserDto>(user);
// Mapster
TypeAdapterConfig<User, UserDto>.NewConfig()
.Map(dest => dest.FullName,
src => src.FirstName + " " + src.LastName);
UserDto dto = user.Adapt<UserDto>();Adapt به صورت مستقیم بر روی لیست، کمی شهودیتر به نظر میرسد.// AutoMapper List<UserDto> dtoList = mapper.Map<List<UserDto>>(userList); // Mapster List<UserDto> dtoList = userList.Adapt<List<UserDto>>();
ProjectToType سادهتر و روانتر است.// AutoMapper
var users = dbContext.Users
.ProjectTo<UserDto>(config)
.ToList();
// Mapster
var users = dbContext.Users
.ProjectToType<UserDto>()
.ToList();var config = new TypeAdapterConfig();
config.NewConfig<User, UserDto>()
.Map(dest => dest.SerialNumber, src => src.SerialNumber)
.Ignore(dest => dest.Password);
services.AddSingleton(config);
services.AddSingleton<IMapper, ServiceMapper>();app.MapPost("/test", (IMapper mapper) =>
{
var user = new User();
var dto=mapper.Map<UserDto>(user);
//or
var dto2 = new UserDto();
mapper.Map(dto, dto2);
});public interface IMapConfiguration
{
TypeAdapterConfig AddConfig(TypeAdapterConfig config);
}public static class MapConfigurationService
{
public static IServiceCollection ScanMapConfigurations(this IServiceCollection services, Assembly assembly)
{
var types = System.Reflection.Assembly.GetExecutingAssembly().GetTypes()
.Where(t => t.IsClass && t.IsPublic && t.GetInterfaces().Contains(typeof(IMapConfiguration)))
.Select(t => (IMapConfiguration)Activator.CreateInstance(t))
.ToList();
var config = new TypeAdapterConfig();
foreach (var type in types)
{
type.AddConfig(config);
}
services.AddSingleton(config);
services.AddSingleton<IMapper, ServiceMapper>();
return services;
}
}builder.Services.ScanMapConfigurations(typeof(UserConfig).Assembly);
public class UserConfig:IMapConfiguration
{
public TypeAdapterConfig AddConfig(TypeAdapterConfig config)
{
config.NewConfig<User, UserDto>()
.Map(dest => dest.SerialNumber, src => src.SerialNumber)
.Ignore(dest => dest.Password);
return config;
}
}public class EmailConfig:IMapConfiguration
{
public TypeAdapterConfig AddConfig(TypeAdapterConfig config)
{
config.NewConfig<Email, string>()
.MapWith(src => src.EmailAddress);
config.NewConfig<string, Email>()
.MapWith(src => Email.Create(src));
return config;
}
}