Отображение сущности в dto с интерфейсами - PullRequest
0 голосов
/ 09 октября 2018

У меня есть класс сущностей, который я извлекаю из базы данных:

public class User{
    public string Username {get; set;}
    public List<IAddress> Addresses {get; set;}
}

public class Address: IAddress{
    public string Line1 {get; set;}
    public string Line2 {get; set;}
}
public class AddressExtended:Address, IAddress{
    public string Line3 {get; set;}
    public string Line4 {get; set;}
}
public interface IAddress{
}

Я использую Automapper для сопоставления этой сущности с зеркальным DTO:

public class UserDto{
    [JsonProperty("username")]
    public string Username { get; set; }
    [JsonProperty("addresses")]
    public List<IAddressDto> Addresses { get; set; }
}

public class AddressDto: IAddressDto{
    [JsonProperty("line1")]
    public string Line1 { get; set; }
    [JsonProperty("line2")]
    public string Line2 { get; set; }
}
public class AddressExtendedDto:AddressDto, IAddressDto{
    [JsonProperty("line3")]
    public string Line3 { get; set; }
    [JsonProperty("line4")]
    public string Line4 { get; set; }
}
public interface IAddressDto{
}

Конфигурация Automapper - этоследующее:

CreateMap<IAddress, IAddressDto>();
CreateMap<Address, AddressDto>();
CreateMap<AddressExtended, AddressExtendedDto>();

Проблема в том, что когда я запускаю свое приложение, если в сущности у меня есть 2 адреса и 1 addressExtended, в DTO свойство Addresses () отображается следующим образом:

[   
 {Proxy<MyProject.Models.Dto.IAddressDto_MyProject_Version=1.0.0.0_Culture=neutral_PublicKeyToken=null>},
 {Proxy<MyProject.Models.Dto.IAddressDto_MyProject_Version=1.0.0.0_Culture=neutral_PublicKeyToken=null>},
 {Proxy<MyProject.Models.Dto.IAddressDto_MyProject_Version=1.0.0.0_Culture=neutral_PublicKeyToken=null>}
]

Свойство Username правильно оценено.

Что мне не хватает?

ОБНОВЛЕНИЕ

Iдобавил сюда скрипач:

https://dotnetfiddle.net/ZkUZgp

1 Ответ

0 голосов
/ 09 октября 2018

Насколько мне известно, одним из подходов к решению проблемы является использование Construct с использованием приведенного ниже кода

cfg.CreateMap<Address, AddressDto>();
cfg.CreateMap<AddressExtended, AddressExtendedDto>();
cfg.CreateMap<IAddress, IAddressDto>().ConstructUsing((IAddress addressDto) =>
{
    if (addressDto is AddressExtended) return Mapper.Map<AddressExtendedDto>(addressDto);
    return Mapper.Map<AddressDto>(addressDto);
});

Редактировать 1: Вот окончательный ответ, и он решает вашу проблему

cfg.CreateMap<Address, AddressDto>();
cfg.CreateMap<AddressExtended, AddressExtendedDto>();
cfg.CreateMap<IAddress, IAddressDto>().ConstructUsing((addressDto, ctx) =>
{
    var destination = Mapper.Instance.ConfigurationProvider.GetAllTypeMaps()
                        .First(t => t.SourceType == addressDto.GetType());
    return ctx.Mapper.Map(addressDto, addressDto.GetType(), destination.DestinationType) as IAddressDto;
});

Вместо того, чтобы получать тип назначения с помощью LINQ, вы можете создать словарь и использовать его для более быстрого выполнения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...