1

I'm trying to create a mapping from our entity models to a Dto but I'm failing everytime in trying to create the mapping.

I have two domain classes. This is a simplification of our model (Device for instance has a lot more properties that represent a bunch of different things):

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

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

I then want to map DeviceAccessToken instances to this DeviceDto (also simplified, it has most of the fields present in the original Device model):

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

Is there a way to create this mapping without explicitly specifying all fields of the Device domain model in the mapping?

This is effectively what I want, represented by an AutoMapper profile:

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());
    }
}

The .ForAllMembers call was a failed attempt to make this work, it must not function like I envisioned it.

I understand I could do this by specifying every property of the Device in the DeviceAccessToken->DeviceDto mapping, but it would be a nightmare and very redundant since the names are the same.

hutchonoid
  • 32,982
  • 15
  • 99
  • 104
julealgon
  • 7,072
  • 3
  • 32
  • 77

1 Answers1

1

"Is there a way to create this mapping without explicitly specifying all fields of the Device domain model in the mapping?"

Yes, you can use the naming conventions in your Dto object and this would prevent you having to enter them in the create map.

As an example:

Your values Key and Secret exist in DeviceAccessToken and DeviceDto they will not need to be mapped. As Device is a nested object your dto can use the convention of DeviceName.

Example:

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);
    }
}

Working fiddle

hutchonoid
  • 32,982
  • 15
  • 99
  • 104
  • A little after I posted the question I found [this article](https://github.com/AutoMapper/AutoMapper/wiki/Flattening) that explains this convention you talk about, and for now I decided to use it. But would there be a way to, also by convention, make automapper recognize the properties without having to prefix them with the nested property name? In my case, I had to create two very similar Dtos because one of them needed to have this convention, while the other did not. In some places, I need to map a `Device` directly to a `DeviceDto`, and that would make lots of things simpler on my end. – julealgon Oct 10 '14 at 20:15
  • 1
    @julealgon Hi, I know what you mean but it seems different from the original question. I would create a new question, you will get more people trying to answer it. I have used the INamingConvention to change the conventions before, that might be something you could use. https://github.com/AutoMapper/AutoMapper/blob/d6eaf7025932ebedccbf8c339a155e9f4ae5c5d8/src/AutoMapper/INamingConvention.cs – hutchonoid Oct 14 '14 at 11:19