Skip to content

Commit 940f6b1

Browse files
committed
Support for data source specification with .Map(s => s.Value, t => t.Member)
1 parent a85a9bf commit 940f6b1

File tree

6 files changed

+58
-14
lines changed

6 files changed

+58
-14
lines changed

AgileMapper.UnitTests/Configuration/Inline/WhenConfiguringDataSourcesInline.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -131,15 +131,13 @@ public void ShouldApplyInlineConstantDataSourceExpressionsConditionally()
131131
.Map(source1)
132132
.ToANew<PublicField<string>>(c => c
133133
.If((pp, pf) => pp.Value != "No")
134-
.Map("Maybe?")
135-
.To(pf => pf.Value));
134+
.Map("Maybe?", pf => pf.Value));
136135

137136
var result2 = mapper
138137
.Map(source2)
139138
.ToANew<PublicField<string>>(c => c
140139
.If((pp, pf) => pp.Value != "No")
141-
.Map("Maybe?")
142-
.To(pf => pf.Value));
140+
.Map("Maybe?", pf => pf.Value));
143141

144142
result1.Value.ShouldBe("Maybe?");
145143
result2.Value.ShouldBe("No");

AgileMapper.UnitTests/Configuration/WhenConfiguringDataSources.cs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -134,8 +134,7 @@ public void ShouldApplyMultipleConfiguredMembersBySourceType()
134134
mapper.WhenMapping
135135
.From<Customer>()
136136
.To<PublicProperty<string>>()
137-
.Map((p, t) => p.Discount)
138-
.To(x => x.Value);
137+
.Map(c => c.Discount, pp => pp.Value);
139138

140139
var personSource = new Person { Name = "Wilma" };
141140
var personResult = mapper.Map(personSource).ToANew<PublicProperty<string>>();
@@ -330,8 +329,7 @@ public void ShouldApplyAConfiguredMemberInARootEnumerable()
330329
mapper.WhenMapping
331330
.From<Person>()
332331
.To<PublicField<string>>()
333-
.Map(ctx => ctx.Source.Name)
334-
.To(x => x.Value);
332+
.Map(p => p.Name, pf => pf.Value);
335333

336334
var source = new[] { new Person { Name = "Mr Thomas" } };
337335
var result = mapper.Map(source).ToANew<List<PublicField<string>>>();
@@ -691,8 +689,7 @@ public void ShouldApplyAConfiguredComplexTypeEnumerable()
691689
mapper.WhenMapping
692690
.From(source)
693691
.To<PublicProperty<IEnumerable<Person>>>()
694-
.Map((s, pp) => s.People)
695-
.To(pp => pp.Value);
692+
.Map(s => s.People, pp => pp.Value);
696693

697694
var result = mapper.Map(source).ToANew<PublicProperty<IEnumerable<Person>>>();
698695

AgileMapper/Api/Configuration/CustomDataSourceTargetMemberSpecifier.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ private ConfiguredLambdaInfo GetValueLambdaInfo<TTargetValue>()
164164
#endif
165165
if ((customValueLambda.Body.NodeType != CONSTANT) ||
166166
(typeof(TTargetValue) == typeof(object)) ||
167-
customValueLambda.ReturnType.IsAssignableTo(typeof(TTargetValue)))
167+
customValueLambda.ReturnType.IsAssignableTo(typeof(TTargetValue)))
168168
{
169169
return ConfiguredLambdaInfo.For(customValueLambda);
170170
}

AgileMapper/Api/Configuration/IRootMappingConfigurator.cs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,23 @@ IMappingConfigContinuation<TSource, TTarget> CreateInstancesUsing<TFactory>(TFac
9999
IMappingConfigContinuation<TSource, TTarget> IgnoreTargetMembersWhere(
100100
Expression<Func<TargetMemberSelector, bool>> memberFilter);
101101

102+
/// <summary>
103+
/// Configure a custom data source for the given <paramref name="targetMember"/> when mapping from and to the
104+
/// source and target types being configured. The factory expression is passed a context object containing the
105+
/// current mapping's source and target objects.
106+
/// </summary>
107+
/// <typeparam name="TSourceValue">The type of the custom value being configured.</typeparam>
108+
/// <typeparam name="TTargetValue">The target member's type.</typeparam>
109+
/// <param name="valueFactoryExpression">The expression to map to the configured target member.</param>
110+
/// <param name="targetMember">The target member to which to apply the configuration.</param>
111+
/// <returns>
112+
/// An IMappingConfigContinuation to enable further configuration of mappings from and to the source
113+
/// and target type being configured.
114+
/// </returns>
115+
IMappingConfigContinuation<TSource, TTarget> Map<TSourceValue, TTargetValue>(
116+
Expression<Func<TSource, TSourceValue>> valueFactoryExpression,
117+
Expression<Func<TTarget, TTargetValue>> targetMember);
118+
102119
/// <summary>
103120
/// Configure a custom data source for a particular target member when mapping from and to the source and
104121
/// target types being configured. The factory expression is passed a context object containing the current
@@ -164,5 +181,21 @@ ICustomMappingDataSourceTargetMemberSpecifier<TSource, TTarget> MapFunc<TSourceV
164181
/// custom constant value should be applied.
165182
/// </returns>
166183
ICustomMappingDataSourceTargetMemberSpecifier<TSource, TTarget> Map<TSourceValue>(TSourceValue value);
184+
185+
/// <summary>
186+
/// Configure a constant value for the given <paramref name="targetMember"/> when mapping from and to the
187+
/// source and target types being configured.
188+
/// </summary>
189+
/// <typeparam name="TSourceValue">The type of the custom constant value being configured.</typeparam>
190+
/// <typeparam name="TTargetValue">The target member's type.</typeparam>
191+
/// <param name="value">The constant value to map to the configured target member.</param>
192+
/// <param name="targetMember">The target member to which to apply the configuration.</param>
193+
/// <returns>
194+
/// An IMappingConfigContinuation to enable further configuration of mappings from and to the source
195+
/// and target type being configured.
196+
/// </returns>
197+
IMappingConfigContinuation<TSource, TTarget> Map<TSourceValue, TTargetValue>(
198+
TSourceValue value,
199+
Expression<Func<TTarget, TTargetValue>> targetMember);
167200
}
168201
}

AgileMapper/Api/Configuration/MappingConfigurator.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,13 @@ public PostEventMappingConfigStartingPoint<TSource, TTarget> After
318318

319319
#region Map Overloads
320320

321+
public IMappingConfigContinuation<TSource, TTarget> Map<TSourceValue, TTargetValue>(
322+
Expression<Func<TSource, TSourceValue>> valueFactoryExpression,
323+
Expression<Func<TTarget, TTargetValue>> targetMember)
324+
{
325+
return GetValueFactoryTargetMemberSpecifier<TSourceValue>(valueFactoryExpression).To(targetMember);
326+
}
327+
321328
public ICustomMappingDataSourceTargetMemberSpecifier<TSource, TTarget> Map<TSourceValue>(
322329
Expression<Func<IMappingData<TSource, TTarget>, TSourceValue>> valueFactoryExpression)
323330
{
@@ -349,6 +356,13 @@ public ICustomMappingDataSourceTargetMemberSpecifier<TSource, TTarget> MapFunc<T
349356
public ICustomMappingDataSourceTargetMemberSpecifier<TSource, TTarget> Map<TSourceValue>(TSourceValue value)
350357
=> GetConstantValueTargetMemberSpecifier(value);
351358

359+
public IMappingConfigContinuation<TSource, TTarget> Map<TSourceValue, TTargetValue>(
360+
TSourceValue value,
361+
Expression<Func<TTarget, TTargetValue>> targetMember)
362+
{
363+
return GetConstantValueTargetMemberSpecifier(value).To(targetMember);
364+
}
365+
352366
ICustomProjectionDataSourceTargetMemberSpecifier<TSource, TTarget> IRootProjectionConfigurator<TSource, TTarget>.Map<TSourceValue>(
353367
TSourceValue value)
354368
{

AgileMapper/Configuration/ConfiguredLambdaInfo.cs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,12 +54,14 @@ private static Type[] GetContextTypes(Type[] funcArguments)
5454
return funcArguments;
5555
}
5656

57-
if (funcArguments[0].IsGenericType())
57+
var firstArgument = funcArguments[0];
58+
59+
if (firstArgument.IsGenericType() && !firstArgument.IsAnonymous())
5860
{
59-
return funcArguments[0].GetGenericTypeArguments();
61+
return firstArgument.GetGenericTypeArguments();
6062
}
6163

62-
return new[] { funcArguments[0] };
64+
return new[] { firstArgument };
6365
}
6466

6567
public static ConfiguredLambdaInfo ForFunc<TFunc>(TFunc func, params Type[] argumentTypes)

0 commit comments

Comments
 (0)