A better way to use AutoMapper to flatten nested objects?

John picture John · Jul 4, 2011 · Viewed 16.8k times · Source

I have been flattening domain objects into DTOs as shown in the example below:

public class Root
{
    public string AParentProperty { get; set; }
    public Nested TheNestedClass { get; set; }
}

public class Nested
{
    public string ANestedProperty { get; set; }
}

public class Flattened
{
    public string AParentProperty { get; set; }
    public string ANestedProperty { get; set; }
}

// I put the equivalent of the following in a profile, configured at application start
// as suggested by others:

Mapper.CreateMap<Root, Flattened>()
      .ForMember
       (
          dest => dest.ANestedProperty
          , opt => opt.MapFrom(src => src.TheNestedClass.ANestedProperty)
       );

// This is in my controller:
Flattened myFlattened = Mapper.Map<Root, Flattened>(myRoot);

I have looked at a number of examples, and so far this seems to be the way to flatten a nested hierarchy. If the child object has a number of properties, however, this approach doesn't save much coding.

I found this example:

http://consultingblogs.emc.com/owainwragg/archive/2010/12/22/automapper-mapping-from-multiple-objects.aspx

but it requires instances of the mapped objects, required by the Map() function, which won't work with a profile as I understand it.

I am new to AutoMapper, so I would like to know if there is a better way to do this.

Answer

Jag picture Jag · Nov 24, 2011

In the latest version of AutoMapper, there's a naming convention you can use to avoid multiple .ForMember statements.

In your example, if you update your Flattened class to be:

public class Flattened
{
    public string AParentProperty { get; set; }
    public string TheNestedClassANestedProperty { get; set; }
}

You can avoid the use of the ForMember statement:

Mapper.CreateMap<Root, Flattened>();

Automapper will (by convention) map Root.TheNestedClass.ANestedProperty to Flattened.TheNestedClassANestedProperty in this case. It looks less ugly when you're using real class names, honest!