Home > Software design >  AutoMapper - Mapping list of objects to bigger list of objects
AutoMapper - Mapping list of objects to bigger list of objects

Time:11-16

Consider the following classes:

public class Colli
{
    public int Count { get; set; }

    public string Description { get; set; }
}

public class Shipment
{
    public List<Colli> Collis { get; set; }
}

public class ShipmentDto
{
    public List<ColliDto> Collis { get; set; }
}

public class ColliDto
{
    public string Description { get; set; }
}

I want the list of Collis to generate a new list of ColliDtos all with the same description based on the Count of a Colli.

Example expected input/output in JSON:

{
    "collis": [
        {
            "count": 2,
            "description": "Colli 1"
        },
        {
            "count": 1,
            "description": "Colli 2"
        }
    ]
}
{
    "collis": [
        {
            "description": "Colli 1"
        },
        {
            "description": "Colli 1"
        },
        {
            "description": "Colli 2"
        }
    ]
}

(The real classes have more fields - this is just a minimal working example)

My research indicates that it should be possible to solve it using an ITypeConverter and I tried creating the following:

public class ColliConverter : ITypeConverter<Colli, List<ColliDto>>
{
    public List<ColliDto> Convert(Colli source, List<ColliDto> destination, ResolutionContext context)
    {
        var retval = new List<ColliDto>();
        for (int i = 0; i < source.Count; i  )
        {
            retval.Add(context.Mapper.Map<ColliDto>(source));
        }
        return retval;
    }
}

With the following mapping profile:

CreateMap<Colli, List<ColliDto>>().ConvertUsing<ColliConverter>();

However, setting a breakpoint in the converter class told me it wasn't being used.

Can this be accomplished with AutoMapper or should I go the 'old route' and do a manual mapping of this class?

CodePudding user response:

Solution 1

  1. Create ShipmentConverter type converter for mapping from the Shipment object to the ShipmentDto object.
public class ShipmentConverter : ITypeConverter<Shipment, ShipmentDto>
{
    public ShipmentDto Convert(Shipment source, ShipmentDto destination, ResolutionContext context)
    {
        destination = new ShipmentDto();
        destination.Collis = new List<ColliDto>();
        
        foreach (var colli in source.Collis)
        {
            for (int i = 0; i < colli.Count; i  )
            {
                destination.Collis.Add(context.Mapper.Map<ColliDto>(colli));
            }
        }
            
        return destination;
    }
}
  1. Mapping profile for Shipment.
CreateMap<Colli, ColliDto>();

CreateMap<Shipment, ShipmentDto>()
    .ConvertUsing<ShipmentConverter>();

Demo Solution 1 @ .NET Fiddle


Solution 2

  1. Create ColliListConverter type converter for mapping from the Colli list to the ColliDto list.
public class ColliListConverter : ITypeConverter<List<Colli>, List<ColliDto>>
{
    public List<ColliDto> Convert(List<Colli> source, List<ColliDto> destination, ResolutionContext context)
    {
        var retval = new List<ColliDto>();
        foreach (var colli in source)
        {
            for (int i = 0; i < colli.Count; i  )
            {
                retval.Add(context.Mapper.Map<ColliDto>(colli));
            }
        }
            
        return retval;
    }
}
  1. Mapping profile for Shipment.
cfg.CreateMap<Colli, ColliDto>();

cfg.CreateMap<List<Colli>, List<ColliDto>>()
    .ConvertUsing<ColliListConverter>();

cfg.CreateMap<Shipment, ShipmentDto>();

Demo Solution 2 @ .NET Fiddle

  • Related