Mapping from Dictionary to Dictionary

1747 views
Skip to first unread message

Can Gencer

unread,
Apr 16, 2011, 7:02:43 PM4/16/11
to AutoMapper-users
I have two classes.

class A
{
IDictionary<string, B> Dictionary;
}

class AViewModel
{
IDictionary<string, BViewModel> Dictionary;
}

I wanted to map A to AViewModel. Mapping exists for B -> BViewModel.
However AutoMapper could not map this automatically. I wrote a custom
resolver, which works like this:

Mapper.CreateMap<A, AViewModel>()
.ForMember(target =>
target.Dictionary,
config => config.ResolveUsing(new
DictionaryMapper<A, AViewModell>
(source => source.Dictionary, target =>
target.Dictionary)));


The DictionaryMapper is implemented like this (I am not pasting the
whole code here) :

public class DictionaryMapper<TSource, TDestination> :
ValueResolver<TSource, IDictionary>
{
public DictionaryMapper(Expression<Func<TSource, object>>
sourceMemberExpression,
Expression<Func<TDestination, object>>
destinationMemberExpression) {... }

protected override IDictionary ResolveCore(TSource source)
{
...
}
}

It basically uses reflection to create a dictionary of the appropriate
type, and uses AutoMapper to map each source Key/Value pair to the
target Key/Value pair. Is this a good way to implement this? I would
love some feedback.

Jimmy Bogard

unread,
Apr 19, 2011, 9:28:49 AM4/19/11
to automapp...@googlegroups.com
A dictionary mapper already exists that maps from keys to keys and values to values. Is that not working for you?


--
You received this message because you are subscribed to the Google Groups "AutoMapper-users" group.
To post to this group, send email to automapp...@googlegroups.com.
To unsubscribe from this group, send email to automapper-use...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/automapper-users?hl=en.


Can Gencer

unread,
Apr 19, 2011, 11:04:51 AM4/19/11
to AutoMapper-users
Hi Jimmy,

No it didn't seem to have work for me. Can post a code snippet that
uses it?

Jimmy Bogard

unread,
Apr 19, 2011, 9:26:50 PM4/19/11
to automapp...@googlegroups.com
Here's the test I have in the codebase:

public class When_mapping_to_a_generic_dictionary_interface_with_mapped_value_pairs : SpecBase
{
private Destination _result;

public class Source
{
public Dictionary<string, SourceValue> Values { get; set; }
}

public class SourceValue
{
public int Value { get; set; }
}

public class Destination
{
public IDictionary<string, DestinationValue> Values { get; set; }
}

public class DestinationValue
{
public int Value { get; set; }
}

protected override void Establish_context()
{
Mapper.CreateMap<Source, Destination>();
Mapper.CreateMap<SourceValue, DestinationValue>();
}

protected override void Because_of()
{
var source = new Source
{
Values = new Dictionary<string, SourceValue>
{
{"Key1", new SourceValue {Value = 5}},
{"Key2", new SourceValue {Value = 10}},
}
};

_result = Mapper.Map<Source, Destination>(source);
}

[Test]
public void Should_perform_mapping_for_individual_values()
{
_result.Values.Count.ShouldEqual(2);

_result.Values["Key1"].Value.ShouldEqual(5);
_result.Values["Key2"].Value.ShouldEqual(10);
}
}

Does that look similar?

Can Gencer

unread,
Apr 20, 2011, 1:59:31 AM4/20/11
to AutoMapper-users
That test works for me. Strange thing, the error must have been
somewhere else. I googled Automapper dictionary and ended up with a
bunch of hits saying dictionaries are not supported by Automapper.
i.e. here is the link:
http://groups.google.com/group/fluent-nhibernate/browse_thread/thread/bd9baab0f5032208/b2cf66e1651ccf68?lnk=raot&fwc=1
must be old.

Jimmy Bogard

unread,
Apr 20, 2011, 8:10:34 AM4/20/11
to automapp...@googlegroups.com
sigh

Not your fault, but two projects picked the same name at the same time. Fluent NHibernate has an auto-ORM-mapper called the automapper.

It also confuses all of my google alerts.

Thanks,

Jimmy

corneliu remus

unread,
Sep 30, 2020, 4:41:44 AM9/30/20
to AutoMapper-users
Hi, I know that this is a very old topic, but I have a problem where I have to map dictionary to dictionary with different keys. 

public class Dest
{
     Dictionary<TextSection, TextPreferences> DestProp
}


public class Source
{
     Dictionary<TextSectionEnum, TextPreferences> SourceProp
}

Where TextSection is an enumeration class and TextSectionEnum is a enum type.

public class TextSection
{
public static readonly TextSection Body = new TextSection((int)TextSectionEnum.Body, TextSectionEnum.Body.ToString(), SystemRestrictions.BrandIdentityConstants.TextPreference.BodyTextSize.ToString());

private TextSection(int id, string name, string value)
: base(id, name, value)
{
}

public enum TextSectionEnum : int
{
Body = 1,
}
}
}

Following is my mapping

this.CreateMap< Source  ,  Dest  >() 
      .ForMember(dest => dest. DestProp  , opt => opt.MapFrom(src => src. SourceProp  ))

this.CreateMap<KeyValuePair<TextSectionEnum, CreateBrandRequest.TextPreferences>, KeyValuePair<TextSection, CreateBrandCommand.TextPreferences>>()
.ConstructUsing(kv => new KeyValuePair<TextSection, CreateBrandCommand.TextPreferences>(
Enumeration.GetAll<TextSection>().FirstOrDefault(ts => kv.Key == (TextSectionEnum)ts.Id),
new CreateBrandCommand.TextPreferences
{
Bold = kv.Value.Bold,
FontColourId = kv.Value.FontColourId,
FontFamilyId = kv.Value.FontFamilyId,
FontSize = kv.Value.FontSize,
Italic = kv.Value.Italic,
Underlined = kv.Value.Underlined,
}));

When calling Map on the source, the dest's destProp is empty.
Reply all
Reply to author
Forward
0 new messages