Automapper: Mapping properties of type Dictionary<string, string>

Created on 17 Jul 2020  路  6Comments  路  Source: AutoMapper/AutoMapper

Hello! Thanks for an awesome library!

I've run into a scenario where mapping objects with Dictionary<string, string> properties doesn't end up as I would expect it to, but this could of course be the intended behavior and perhaps I have just missed it in the documentation?

Source/destination types

Sources:

public class Box
{
    public Dictionary<string, string> Dict { get; set; }
}

public class Tote
{
    public Dictionary<string, string> Dict { get; set; }
}

Targets:

public class BoxDto
{
    public BoxDto(Dictionary<string, string> dict)
    {
        Dict = dict;
    }

    public Dictionary<string, string> Dict { get; }
}

public class ToteDto
{
    public ToteDto(Dictionary<string, string> dict)
    {
        Dict = dict;
    }
    public Dictionary<string, string> Dict { get; }
}

Mapping configuration

var config = new MapperConfiguration(cfg =>
{
    cfg.CreateMap<Box, BoxDto>();
    cfg.CreateMap<Tote, ToteDto>().ConstructUsing(src => new ToteDto(src.Dict));
});
var mapper = new Mapper(config);

Version: x.y.z

AutoMapper 10.0.0

Expected behavior

When I run:

var tote = new Tote { Dict = new Dictionary<string, string> { {"key", "value" } } };
var toteDto = mapper.Map<ToteDto>(tote);

I would expect the dictionary toteDto.Dict to not be empty, because if I do:

var box = new Box { Dict = new Dictionary<string, string> { {"key", "value" } } };
var boxDto = mapper.Map<BoxDto>(box);

boxDto.Dict gets all entries from source dictionary.

Actual behavior

Target's dictionary does not get the entries from source's dictionary when configuring mapping with .ConstructUsing()

Steps to reproduce

Created a fiddle for the scenario:
https://dotnetfiddle.net/tSNXwj

Question

All 6 comments

Check the execution plan. Just remove ConstructUsing. Your own code makes sure that dictionary is both the source and the destination for the mapping, the destination is first cleared and then there's nothing to copy.

Or maybe you mean ConvertUsing? I don't know :) Once you understand why, you'll figure it out.

Thank you @lbargaoanu for the swift reply! Is destination is first cleared something added in the newer releases of AutoMapper? Because I think my expected scenario above worked fine up until recently. However, I understand what's happening here from your comment and easy for me to sort out. 馃憤

https://docs.automapper.org/en/latest/10.0-Upgrade-Guide.html#all-collections-are-mapped-by-default-even-if-they-have-no-setter

To share that same dictionary instance, switch to ConvertUsing. Mapping it will copy the data, changing the code. Although perhaps that makes more sense, it depends.

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

vadimshaporov picture vadimshaporov  路  7Comments

dmdymov picture dmdymov  路  3Comments

AndyAyersMS picture AndyAyersMS  路  5Comments

WellspringCS picture WellspringCS  路  5Comments

zolakt picture zolakt  路  4Comments