Skip to content

Commit 954640c

Browse files
committed
Support for different map-to-null conditions for derived types
1 parent 609baa6 commit 954640c

File tree

5 files changed

+64
-7
lines changed

5 files changed

+64
-7
lines changed

AgileMapper.UnitTests/Configuration/WhenMappingToNull.cs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,43 @@ public void ShouldOverwriteAPropertyToNull()
9393
}
9494
}
9595

96+
[Fact]
97+
public void ShouldApplyConfiguredConditionsToDerivedTypes()
98+
{
99+
using (var mapper = Mapper.CreateNew())
100+
{
101+
mapper.WhenMapping
102+
.To<Product>()
103+
.If((o, p) => p.Price.Equals(0))
104+
.MapToNull();
105+
106+
mapper.WhenMapping
107+
.To<MegaProduct>()
108+
.If((o, p) => p.HowMega == 0)
109+
.MapToNull();
110+
111+
var nonMatchingProductSource = new { Price = 123 };
112+
var nonMatchingProductResult = mapper.Map(nonMatchingProductSource).ToANew<Product>();
113+
114+
nonMatchingProductResult.Price.ShouldBe(123);
115+
116+
var matchingProductSource = new { Price = 0 };
117+
var matchingProductResult = mapper.Map(matchingProductSource).ToANew<Product>();
118+
119+
matchingProductResult.ShouldBeNull();
120+
121+
var nonMatchingMegaProductSource = new { HowMega = 0.99 };
122+
var nonMatchingMegaProductResult = mapper.Map(nonMatchingMegaProductSource).ToANew<MegaProduct>();
123+
124+
nonMatchingMegaProductResult.HowMega.ShouldBe(0.99);
125+
126+
var matchingMegaProductSource = new { HowMega = 0.00 };
127+
var matchingMegaProductResult = mapper.Map(matchingMegaProductSource).ToANew<MegaProduct>();
128+
129+
matchingMegaProductResult.ShouldBeNull();
130+
}
131+
}
132+
96133
[Fact]
97134
public void ShouldErrorIfConditionsAreConfiguredForTheSameType()
98135
{

AgileMapper/Configuration/MapToNullCondition.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,26 @@
11
namespace AgileObjects.AgileMapper.Configuration
22
{
3+
using System;
34
using System.Linq.Expressions;
45
using Members;
56
using ObjectPopulation;
67

78
internal class MapToNullCondition : UserConfiguredItemBase
89
{
10+
private readonly Type _targetType;
11+
912
public MapToNullCondition(MappingConfigInfo configInfo)
1013
: base(configInfo)
1114
{
15+
_targetType = configInfo.TargetType;
1216
}
1317

14-
protected override bool ConditionsAvoidConflict(UserConfiguredItemBase otherConfiguredItem) => false;
18+
public override bool ConflictsWith(UserConfiguredItemBase otherConfiguredItem)
19+
{
20+
var otherCondition = (MapToNullCondition)otherConfiguredItem;
21+
22+
return otherCondition._targetType == _targetType;
23+
}
1524

1625
protected override Expression GetConditionOrNull(IMemberMapperData mapperData, CallbackPosition position)
1726
{

AgileMapper/Configuration/MappingConfigInfo.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,9 @@ public MappingConfigInfo ForTargetType(Type targetType)
7474
return this;
7575
}
7676

77+
public bool IsForTargetType(MappingConfigInfo otherConfigInfo)
78+
=> TargetType.IsAssignableFrom(otherConfigInfo.TargetType);
79+
7780
public bool HasSameTargetTypeAs(MappingConfigInfo otherConfigInfo) => TargetType == otherConfigInfo.TargetType;
7881

7982
public bool HasCompatibleTypes(MappingConfigInfo otherConfigInfo)

AgileMapper/Configuration/UserConfigurationSet.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
internal class UserConfigurationSet
1313
{
1414
private readonly ICollection<ObjectTrackingMode> _trackingModeSettings;
15-
private readonly ICollection<MapToNullCondition> _mapToNullConditions;
15+
private readonly List<MapToNullCondition> _mapToNullConditions;
1616
private readonly ICollection<NullCollectionsSetting> _nullCollectionSettings;
1717
private readonly ICollection<ConfiguredObjectFactory> _objectFactories;
1818
private readonly ICollection<ConfiguredIgnoredMember> _ignoredMembers;
@@ -66,6 +66,7 @@ public void Add(MapToNullCondition condition)
6666
c => "Type " + c.TargetTypeName + " already has a configured map-to-null condition");
6767

6868
_mapToNullConditions.Add(condition);
69+
_mapToNullConditions.Sort();
6970
}
7071

7172
public Expression GetMapToNullConditionOrNull(IMemberMapperData mapperData)

AgileMapper/Configuration/UserConfiguredItemBase.cs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ protected UserConfiguredItemBase(MappingConfigInfo configInfo, QualifiedMember t
5151

5252
public virtual bool ConflictsWith(UserConfiguredItemBase otherConfiguredItem)
5353
{
54-
if (ConditionsAvoidConflict(otherConfiguredItem))
54+
if (HasConfiguredCondition || otherConfiguredItem.HasConfiguredCondition)
5555
{
5656
return false;
5757
}
@@ -64,9 +64,6 @@ public virtual bool ConflictsWith(UserConfiguredItemBase otherConfiguredItem)
6464
return false;
6565
}
6666

67-
protected virtual bool ConditionsAvoidConflict(UserConfiguredItemBase otherConfiguredItem)
68-
=> HasConfiguredCondition || otherConfiguredItem.HasConfiguredCondition;
69-
7067
protected virtual bool MembersConflict(QualifiedMember otherMember)
7168
=> TargetMember.Matches(otherMember);
7269

@@ -146,7 +143,17 @@ int IComparable<UserConfiguredItemBase>.CompareTo(UserConfiguredItemBase other)
146143

147144
if (ConfigInfo.HasSameSourceTypeAs(other.ConfigInfo))
148145
{
149-
return 0;
146+
if (ConfigInfo.HasSameTargetTypeAs(other.ConfigInfo))
147+
{
148+
return 0;
149+
}
150+
151+
if (ConfigInfo.IsForTargetType(other.ConfigInfo))
152+
{
153+
return 1;
154+
}
155+
156+
return -1;
150157
}
151158

152159
if (ConfigInfo.IsForSourceType(other.ConfigInfo))

0 commit comments

Comments
 (0)