Skip to content

Commit a84b2ca

Browse files
committed
Support for mapping object-typed dictionaries to object-typed dictionaries, re: issue #10 / Caching source and target members according to mapped source and target types / Simplifying AdHocDataSource use
1 parent 93b5177 commit a84b2ca

23 files changed

+161
-40
lines changed

AgileMapper.UnitTests/AgileMapper.UnitTests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@
8080
<Compile Include="Dictionaries\Configuration\WhenConfiguringDictionaryMappingIncorrectly.cs" />
8181
<Compile Include="Dictionaries\Configuration\WhenConfiguringNestedDictionaryMapping.cs" />
8282
<Compile Include="Dictionaries\Configuration\WhenConfiguringTargetDictionaryMapping.cs" />
83+
<Compile Include="Dictionaries\WhenCreatingRootDictionaryMembers.cs" />
8384
<Compile Include="TestClasses\MegaProduct.cs" />
8485
<Compile Include="TestClasses\ProductDto.cs" />
8586
<Compile Include="TestClasses\ProductDtoMega.cs" />
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
namespace AgileObjects.AgileMapper.UnitTests.Dictionaries
2+
{
3+
using System.Collections.Generic;
4+
using AgileMapper.Members;
5+
using Shouldly;
6+
using TestClasses;
7+
using Xunit;
8+
9+
public class WhenCreatingRootDictionaryMembers
10+
{
11+
[Fact]
12+
public void ShouldVarySourceMembersByTargetType()
13+
{
14+
var memberFactory = new QualifiedMemberFactory(MapperContext.Default);
15+
16+
var dictionaryToPersonArraySourceMember = memberFactory
17+
.RootSource<Dictionary<string, Person[]>, Person[]>()
18+
as DictionarySourceMember;
19+
20+
dictionaryToPersonArraySourceMember.ShouldNotBeNull();
21+
22+
// ReSharper disable once PossibleNullReferenceException
23+
dictionaryToPersonArraySourceMember.CouldContainSourceInstance.ShouldBeTrue();
24+
25+
var dictionaryToObjectSourceMember = memberFactory
26+
.RootSource<Dictionary<string, Person[]>, PersonViewModel[]>()
27+
as DictionarySourceMember;
28+
29+
dictionaryToObjectSourceMember.ShouldNotBeSameAs(dictionaryToPersonArraySourceMember);
30+
}
31+
}
32+
}

AgileMapper.UnitTests/Dictionaries/WhenMappingOnToDictionaryMembers.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
public class WhenMappingOnToDictionaryMembers
99
{
1010
[Fact]
11-
public void ShouldMapADictionaryOnToAConvertibleSimpleTypedDictionary()
11+
public void ShouldMapAnIDictionaryOnToAConvertibleSimpleTypedDictionary()
1212
{
1313
var guidOne = Guid.NewGuid();
1414
var guidTwo = Guid.NewGuid();

AgileMapper.UnitTests/Dictionaries/WhenMappingOverDictionaryMembers.cs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,5 +71,42 @@ public void ShouldOverwriteADictionaryToAConvertibleSimpleTypedDictionary()
7171
target.Value["Four"].ShouldBeNull();
7272
target.Value["Five"].ShouldBe(5);
7373
}
74+
75+
// See https://github.com/agileobjects/AgileMapper/issues/10
76+
[Fact]
77+
public void ShouldMapADictionaryMemberOverADictionaryMember()
78+
{
79+
var source = new PublicProperty<Dictionary<string, object>>
80+
{
81+
Value = new Dictionary<string, object>
82+
{
83+
["One!"] = new PersonViewModel { Name = "One!" },
84+
["Two!"] = new PersonViewModel { Name = "Two!" }
85+
}
86+
};
87+
88+
89+
var target = new PublicProperty<Dictionary<string, object>>
90+
{
91+
Value = new Dictionary<string, object>
92+
{
93+
["Two!"] = new PersonViewModel { Name = "Three!" }
94+
}
95+
};
96+
97+
var existingTarget = target.Value;
98+
99+
Mapper.Map(source).Over(target);
100+
101+
target.Value.ShouldBeSameAs(existingTarget);
102+
103+
target.Value.ContainsKey("One!").ShouldBeTrue();
104+
target.Value["One!"].ShouldBeOfType<PersonViewModel>();
105+
((PersonViewModel)target.Value["One!"]).Name.ShouldBe("One!");
106+
107+
target.Value.ContainsKey("Two!").ShouldBeTrue();
108+
target.Value["Two!"].ShouldBeOfType<PersonViewModel>();
109+
((PersonViewModel)target.Value["Two!"]).Name.ShouldBe("Two!");
110+
}
74111
}
75112
}

AgileMapper.UnitTests/Members/WhenDeterminingRecursion.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ public class WhenDeterminingRecursion : MemberTestsBase
1111
public void ShouldNotCountARootMemberAsRecursive()
1212
{
1313
var rootMember = new QualifiedMemberFactory(DefaultMapperContext)
14-
.RootTarget<PublicProperty<string>>();
14+
.RootTarget<Person, PublicProperty<string>>();
1515

1616
rootMember.IsRecursion.ShouldBeFalse();
1717
}

AgileMapper/Api/Configuration/CustomDataSourceTargetMemberSpecifier.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ private bool IsDictionaryEntry(LambdaExpression targetMemberLambda, out Dictiona
101101

102102
var rootMember = (DictionaryTargetMember)_configInfo.MapperContext
103103
.QualifiedMemberFactory
104-
.RootTarget<TTarget>();
104+
.RootTarget<TSource, TTarget>();
105105

106106
entryMember = rootMember.Append(typeof(TSource), entryKey);
107107
return true;

AgileMapper/DataSources/AdHocDataSource.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
namespace AgileObjects.AgileMapper.DataSources
22
{
33
using System.Linq.Expressions;
4+
using Members;
45

56
internal class AdHocDataSource : DataSourceBase
67
{
7-
public AdHocDataSource(IDataSource wrappedDataSource, Expression value)
8-
: base(wrappedDataSource, value)
8+
public AdHocDataSource(IQualifiedMember targetMember, Expression value)
9+
: base(targetMember, value)
910
{
1011
}
1112
}

AgileMapper/DataSources/DataSourceBase.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ public Expression AddCondition(Expression value, Expression alternateBranch = nu
119119
: Expression.IfThen(Condition, value);
120120
}
121121

122-
public Expression GetMemberPopulation(IMemberMapperData mapperData)
122+
public Expression GetTargetMemberPopulation(IMemberMapperData mapperData)
123123
=> mapperData.GetTargetMemberPopulation(Value);
124124
}
125125
}

AgileMapper/DataSources/DataSourceSet.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ public Expression GetPopulationExpression(IMemberMapperData mapperData)
7979
continue;
8080
}
8181

82-
var memberPopulation = dataSource.GetMemberPopulation(mapperData);
82+
var memberPopulation = dataSource.GetTargetMemberPopulation(mapperData);
8383

8484
population = dataSource.AddCondition(memberPopulation, population);
8585
population = dataSource.AddPreCondition(population);

AgileMapper/DataSources/IDataSource.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,6 @@ internal interface IDataSource : IConditionallyChainable
2121

2222
Expression AddCondition(Expression value, Expression alternateBranch = null);
2323

24-
Expression GetMemberPopulation(IMemberMapperData mapperData);
24+
Expression GetTargetMemberPopulation(IMemberMapperData mapperData);
2525
}
2626
}

0 commit comments

Comments
 (0)