AutoMapper: Map to collection from multiple source properties

automapper, c#

Solution

There are at least 2 options. You can use a simple extension method to simplify the mapping or you can create a custom type converter.

public class ConvertSourceToDestination : ITypeConverter<Source, Destination>
{
    public Destination Convert(Source source, Destination destination, ResolutionContext context)
    {
        destination = destination ?? new Destination();
        destination.Children = destination.Children ?? new List<Child>();
        destination.Children.Add(new Child() { Property1 = source.Child1Property1, Property2 = source.Child1Property2 });
        destination.Children.Add(new Child() { Property1 = source.Child2Property1, Property2 = source.Child2Property2 });
        destination.Name = source.Name;

        return destination;
    }
}

public static class SourceExtension
{
    public static IEnumerable<Child> Children(this Source source)
    {
        yield return new Child() { Property1 = source.Child1Property1, Property2 = source.Child1Property2 };
        yield return new Child() { Property1 = source.Child2Property1, Property2 = source.Child2Property2 };
    }

    public static MapperConfiguration CreateMapping()
    {
        var config = new MapperConfiguration(
            cfg =>
            {
                cfg.CreateMap<Source, Destination>()
                .ForMember(dest => dest.Children, opt => opt.MapFrom(src => src.Children()));
            });

        return config;
    }

    public static MapperConfiguration CreateMapping2()
    {
        var config = new MapperConfiguration(
            cfg =>
            {
                cfg.CreateMap<Source, Destination>().ConvertUsing(new ConvertSourceToDestination());

            });

        return config;
    }
}

Problem

UPDATE April 13th, 2018: Automapper 6.1.0 supports unflattening by introducing `ReverseMap`. See release notes here I'm trying to use AutoMapper to unflatten an object. I have a source as follows ``` public class Source { public string Name {get;set;} public string Child1Property1 {get;set;} public string Child1Property2 {get;set;} public string Child2Property1 {get;set;} public string Child2Property2 {get;set;} } ``` I want to map to this to destination ``` public class Destination { public string Name {get;set;} public List<Child> Children {get;set;} } public class Child { public string Property1 {get;set;} public string Property2 {get;set;} } ``` My mapping configuration ``` public static class AutoMapperConfiguration { public static MapperConfiguration Configure() { var config = new MapperConfiguration( cfg => { cfg.CreateMap<Source, Destination>() .ForMember(dest => dest.Children, /* What do I put here?*/)) // I don't think this is correct cfg.CreateMap<Source, Child>() .ForMember(dest => dest.Property1, opt => opt.MapFrom(src => src.Child1Property1)) .ForMember(dest => dest.Property2, opt => opt.MapFrom(src => src.Child1Property2)) .ForMember(dest => dest.Property1, opt => opt.MapFrom(src => src.Child2Property1)) .ForMember(dest => dest.Property2, opt => opt.MapFrom(src => src.Child2Property2)); }); return config; } } ``` Now when I test my code I get using `mapper.Map<List<Child>>(source)` I get a `AutoMapperMappingException: Missing type map configuration or unsupported mapping.` Which make sense, since there isn't a mapping configured to a `List<Child>`. If I do `mapper.Map<Child>(source)`, I get a `Child` instance with all `null` values for the properties. I'm unfortunately not in a position to modify the `Source` class. Is this possible at all with AutoMapper? and if so how?

Original source