It's a little difficult to get it from scratch, but it is possible. You have to create a ITypeConverter<,> and apply this to be used for the conversion.
Be aware, that the ConvertUsing() method has also an overload to simply add an inline function, but you need to have access to the mapper itself to call it for mapping the inner objects to the desired result objects and that's only available with the type converter interface.
public class OrderMappingProfile : Profile
{
public OrderMappingProfile()
{
CreateMap<OrderDto, Order>();
CreateMap<OrderDtoList, List<Order>>().ConvertUsing<CustomConverter>();
}
}
public class CustomConverter : ITypeConverter<OrderDtoList, List<Order>>
{
public List<Order> Convert(OrderDtoList source, List<Order> destination, ResolutionContext context)
{
return context.Mapper.Map<List<Order>>(source.Orders);
}
}
With this in place, you can create the desired list right from the DTO:
public static class Program
{
public static void Main()
{
var config = new MapperConfiguration(cfg => cfg.AddProfile<OrderMappingProfile>());
var mapper = config.CreateMapper();
var orderList = new OrderDtoList { Orders = Enumerable.Range(1, 10).Select(i => new OrderDto { Id = i }).ToArray() };
var orders = mapper.Map<List<Order>>(orderList);
}
}
As Lucian mentioned, there is an overload of ConvertUsing() that provides the context. So you could also inline this, instead of using an own class:
// Use lambda method
CreateMap<OrderDtoList, List<Order>>()
.ConvertUsing((source, _, context) => context.Mapper.Map<List<Order>>(source.Orders));
// Use static method
CreateMap<OrderDtoList, List<Order>>().ConvertUsing(ListConverter);
private static List<Order> ListConverter(OrderDtoList source, List<Order> destination, ResolutionContext context)
{
return context.Mapper.Map<List<Order>>(source.Orders);
}