Я пытаюсь Map
и ReverseMap
ImmutableHashSet
свойство ICollection
, используя AutoMapper
.
. Automapper успешно отображает свойство ImmutableHashSet
в ICollection
, но он не может отобразить ICollection
обратно на ImmutableHashSet
Вот минимальный воспроизводимый пример:
Предположим, у меня есть класс Order
и OrderItem
, как показано ниже:
public class Order
{
private HashSet<OrderItem> _orderItems;
public Order()
{
_orderItems = new HashSet<OrderItem>();
}
public ImmutableHashSet<OrderItem> OrderItems
{
get => _orderItems.ToImmutableHashSet();
private set => _orderItems = value.ToHashSet();
}
public void AddOrderItem(OrderItem orderItem)
{
_orderItems.Add(orderItem);
}
public void RemoveOrderItem(OrderItem orderItem)
{
_orderItems.Add(orderItem);
}
}
public class OrderItem
{
public OrderItem(int orderId, string orderName)
{
OrderId = orderId;
OrderName = orderName;
}
public int OrderId { get; private set; }
public string OrderName { get; private set; }
}
Классы Order
и OrderItem
должны отображаться ниже OrderDto
, а классы
public class OrderDto
{
public ICollection<OrderItem> OrderItems { get; set; }
}
public class OrderItemDto
{
public int OrderId { get; set; }
public string OrderName { get; set; }
}
Класс OrderProfile
ниже определяет профиль Automapper для сопоставления Order
с OrderDto
и наоборот.
public class OrderProfile : Profile
{
public OrderProfile()
{
CreateMap<Order, OrderDto>()
.ReverseMap();
CreateMap<OrderItem, OrderItemDto>()
.ReverseMap();
}
}
public class OrderItemDto
{
public int OrderId { get; set; }
public string OrderName { get; set; }
}
Код для сопоставления и обратного сопоставления классов Order
и OrderDto
:
private static void Map()
{
var mapper = new MapperConfiguration(cfg =>
{
cfg.AddProfile(new OrderProfile());
}).CreateMapper();
var order = new Order();
order.AddOrderItem(new OrderItem(1, "Laptop"));
order.AddOrderItem(new OrderItem(2, "Keyboard"));
// This code maps correctly
var orderDto = mapper.Map<OrderDto>(order);
// This is where I get an exception
var orderMappedBack = mapper.Map<Order>(orderDto);
}
При отображении Order
object
из OrderDto
, я получаю следующее исключение:
System.ArgumentException: System.Collections.Immutable.ImmutableHashSet`1[ReadOnlyCollectionDemo.OrderItem]
needs to have a constructor with 0 args or only optional args.
(Parameter 'type') at lambda_method(Closure , OrderDto , Order , ResolutionContext )
Любые указатели, которые помогут решить эту проблему, высоко ценятся.
Обновление
У меня как-то получилось работать через кастом Converter
. Но я действительно не знаю, как это работает. Я обновил свою конфигурацию маппера следующим образом:
var mapper = new MapperConfiguration(cfg =>
{
cfg.AddProfile(new OrderProfile());
cfg.CreateMap(typeof(ICollection<>), typeof(ImmutableHashSet<>)).ConvertUsing(typeof(HashMapConverter<,>));
}).CreateMapper();
Мой HashMapConverter
класс:
public class HashMapConverter<TCollection, TImmutableHashSet>
: ITypeConverter<ICollection<TCollection>, ImmutableHashSet< TImmutableHashSet>>
{
public ImmutableHashSet< TImmutableHashSet> Convert(
ICollection<TCollection> source,
ImmutableHashSet< TImmutableHashSet> destination,
ResolutionContext context)
{
return ImmutableHashSet<TImmutableHashSet>.Empty;
}
}
Как вы видите, я просто возвращаю пустой ImmutableHashSet
, однако, к моему удивлению, OrderDto
теперь успешно сопоставлен с Order
с правильным номером OrderItems
Count
. Я бы ожидал, что Count
будет 0, так как я возвращаю пустое HashSet
. Я подозреваю, что это работает, потому что OrderItem
и OrderItemDto
также отображаются через AutoMapper
.
Я хотел бы подтвердить свою гипотезу и узнать, является ли это правильным подходом.