Как сопоставить модель с вложенными свойствами с плоским Dto?

Я пытаюсь создать сопоставление наших моделей сущностей с Dto, но каждый раз терплю неудачу, пытаясь создать сопоставление.

У меня есть два класса домена. Это упрощение нашей модели (например, Device имеет гораздо больше свойств, которые представляют кучу разных вещей):

class Device
{
    public int Name {get; set;}
}

class DeviceAccessToken
{
    public Device Device {get; set;}
    public string Key {get; set;}
    public string Secret {get; set;}
}

Затем я хочу сопоставить экземпляры DeviceAccessToken с этим экземпляром DeviceDto (тоже упрощенно, в нем есть большинство полей, присутствующих в исходной модели Device):

class DeviceDto
{
    public int Name {get; set;}
    public string Key {get; set;}
    public string Secret {get; set;}
}

Есть ли способ создать это сопоставление без явного указания всех полей модели предметной области Device в сопоставлении?

Это то, что я хочу, представленное профилем AutoMapper:

class DeviceMappingProfile : Profile
{
    protected override void Configure()
    {
        this.CreateMap<DeviceAccessToken, DeviceDto>();

        this.CreateMap<Device, DeviceDto>()
            .ForMember(dest => dest.Key, opt => opt.Ignore())
            .ForMember(dest => dest.Secret, opt => opt.Ignore());
    }
}

Вызов .ForAllMembers был неудачной попыткой заставить это работать, он не должен работать так, как я предполагал.

Я понимаю, что мог бы сделать это, указав каждое свойство Device в сопоставлении DeviceAccessToken->DeviceDto, но это было бы кошмаром и очень избыточным, поскольку имена одинаковы.


person julealgon    schedule 10.10.2014    source источник


Ответы (1)


"Есть ли способ создать это сопоставление без явного указания всех полей модели домена устройства в сопоставлении?"

Да, вы можете использовать соглашения об именах в вашем объекте Dto, и это избавит вас от необходимости вводить их в карту создания.

В качестве примера:

Ваши значения Key и Secret существуют в DeviceAccessToken и DeviceDto, их не нужно сопоставлять. Поскольку Device является вложенным объектом, ваш dto может использовать соглашение DeviceName.

Пример:

using System;
using AutoMapper;

class Device
{
    public string Name {get; set;}
}

class DeviceAccessToken
{
    public Device Device {get; set;}
    public string Key {get; set;}
    public string Secret {get; set;}
}

class DeviceDto
{
    public string DeviceName {get; set;}
    public string Key {get; set;}
    public string Secret {get; set;}
}

public class Program
{
    public void Main()
    {

        // Configure AutoMapper
        Mapper.CreateMap<DeviceAccessToken, DeviceDto>();       

        var dat = new DeviceAccessToken { Device = new Device { Name = "Dev Name" }, Key = "Key", Secret = "Secret" };

        var dto = Mapper.Map<DeviceDto>(dat);

        Console.WriteLine(dto.DeviceName);
        Console.WriteLine(dto.Key);
        Console.WriteLine(dto.Secret);
    }
}

Рабочая скрипта

person hutchonoid    schedule 10.10.2014
comment
Вскоре после того, как я разместил вопрос, я нашел эту статью, в которой объясняется это соглашение, о котором вы говорите. , и пока я решил использовать его. Но будет ли способ, также по соглашению, заставить automapper распознавать свойства без необходимости добавлять к ним префикс с именем вложенного свойства? В моем случае мне пришлось создать две очень похожие Dtos, потому что одна из них должна была иметь это соглашение, а другая — нет. В некоторых местах мне нужно сопоставить Device напрямую с DeviceDto, и это упростило бы многие вещи с моей стороны. - person julealgon; 11.10.2014
comment
@julealgon Привет, я понимаю, что ты имеешь в виду, но кажется, что это отличается от первоначального вопроса. Я бы создал новый вопрос, вы получите больше людей, пытающихся ответить на него. Раньше я использовал INamingConvention для изменения соглашений, это может быть то, что вы могли бы использовать. github.com/AutoMapper/AutoMapper/blob/ - person hutchonoid; 14.10.2014