Десериализация в автомаппере
Есть код:
CreateMap<Mnemoelement, MnemoelementDTO>()
.ForMember(nameof(MnemoelementDTO.Settings), opt => opt.MapFrom(me => JsonConvert.DeserializeObject<__type__>(me.Settings)));
__type__ - варьируется в зависсимости от свойства me.Type (string)
Например если me.Type == "LINE", то десериаллизоваться должно в тип LineSettings,
если me.Type == "CIRCLE", то десериаллизоваться должно в тип CircleSettings.
Если во внутрь MapFrom как-то вставить switch, то это поможет, только вот как?
Как можно это реализовать?
Ответы (1 шт):
Автор решения: Виталий Шебаниц
→ Ссылка
Чтобы при мапинге выполнять какую-то кастомную логику, можно реализовать свой ResolverMember например так:
public class ResolverMnemoelement : IValueResolver<Mnemoelement, MnemoelementDTO, ISettings>
{
ISettings IValueResolver<Mnemoelement, MnemoelementDTO, ISettings>.Resolve(Mnemoelement source, MnemoelementDTO destination, ISettings destMember, ResolutionContext context)
{
ISettings result = null;
switch (source.Type)
{
case "LINE":
{
result = JsonConvert.DeserializeObject<LineSettings>(source.Settings);
break;
}
case "CIRCLE":
{
result = JsonConvert.DeserializeObject<CircleSettings>(source.Settings);
break;
}
}
return result;
}
}
И потом так использовать:
CreateMap<Mnemoelement, MnemoelementDTO>()
.ForMember(meDTO => meDTO.LinkType, opt => opt.MapFrom(me => Enum.Parse(typeof(EMnemoelementLinkType), me.LinkType)))
.ForMember(meDTO => meDTO.Type, opt => opt.MapFrom(me => Enum.Parse(typeof(EMnemoelementType), me.Type)))
.ForMember(meDTO => meDTO.Settings, opt => opt.MapFrom(new ResolverMnemoelement()));
Это позволит смапить модели:
/// <summary>
/// Элемент на мнемосхеме
/// </summary>
[Table(name: "mnemoelements", Schema = "public")]
public class Mnemoelement : IEntitySingleId<int>
{
/// <summary>
/// Идентификатор
/// </summary>
[Key]
[Column("id")]
public int Id { get; set; }
/// <summary>
/// Тип ссылки
/// MNEMO | GROUP
/// </summary>
[Column("link_type")]
[MaxLength(15)]
[Required]
public string LinkType { get; set; }
/// <summary>
/// Идентификатор для LinkType
/// </summary>
[Column("identifier")]
[MaxLength(50)]
[Required]
public string Identifier { get; set; }
/// <summary>
/// Тип элемента
/// "LINE" | "CIRCLE" | "ICON" | "TEXT" | "LINK"
/// </summary>
[Column("type")]
[MaxLength(50)]
[Required]
public string Type { get; set; }
/// <summary>
/// Настройки для конкретного элемента
/// </summary>
[Column("settings")]
[MaxLength(50)]
[Required]
public string Settings { get; set; }
}
И
public class MnemoelementDTO
{
/// <summary>
/// Идентификатор
/// </summary>
[Display(Name = "Iдентифікатор", ShortName = "#")]
public int Id { get; set; }
/// <summary>
/// Тип ссылки
/// MNEMO | GROUP
/// </summary>
[Display(Name = "Тип посилання")]
public EMnemoelementLinkType LinkType { get; set; }
/// <summary>
/// Идентификатор для LinkType
/// </summary>
[Display(Name = "Iдентифікатор")]
public string Identifier { get; set; }
/// <summary>
/// Тип элемента
/// "LINE" | "CIRCLE" | "ICON" | "TEXT" | "LINK"
/// </summary>
[Display(Name = "Тип елементу")]
public EMnemoelementType Type { get; set; }
/// <summary>
/// Настройки для конкретного элемента
/// </summary>
[Display(Name = "Налаштування")]
public ISettings Settings { get; set; }
}
При этом в модели ISettings может быть любая из доступных моделей настроек
public interface ISettings
{
}
public class LineSettings : ISettings
{
public Tuple<Point, Point> Position { get; set; }
public string Color { get; set; } = "#ffffff";
public double Size { get; set; } = 2.0;
public class Point
{
double X { get; set; }
double Y { get; set; }
public Point(int x, int y)
{
X = x;
Y = y;
}
}
}
public class CircleSettings : ISettings
{
public Point Position { get; set; }
public double Radius { get; set; }
public string Color { get; set; } = "#ffffff";
public double BorderSize { get; set; } = 1.0;
public string BorderColor{ get; set; } = "#ffffff";
public double Size { get; set; } = 2.0;
public class Point
{
double X { get; set; }
double Y { get; set; }
public Point(int x, int y)
{
X = x;
Y = y;
}
}
}
p.s. Решение было найдено в документации автомапера