Skip to content

Commit f95f037

Browse files
committed
Delegating whether a ReadOnlyCollectionWrapper can be used to SourceEnumerableAdapter
1 parent b073784 commit f95f037

File tree

7 files changed

+61
-38
lines changed

7 files changed

+61
-38
lines changed

AgileMapper/ObjectPopulation/Enumerables/DefaultSourceEnumerableAdapter.cs

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,42 +3,37 @@ namespace AgileObjects.AgileMapper.ObjectPopulation.Enumerables
33
using System.Linq.Expressions;
44
using NetStandardPolyfills;
55

6-
internal class DefaultSourceEnumerableAdapter : ISourceEnumerableAdapter
6+
internal class DefaultSourceEnumerableAdapter : SourceEnumerableAdapterBase, ISourceEnumerableAdapter
77
{
8-
private readonly EnumerablePopulationBuilder _builder;
9-
108
public DefaultSourceEnumerableAdapter(EnumerablePopulationBuilder builder)
9+
: base(builder)
1110
{
12-
_builder = builder;
1311
}
1412

15-
public Expression GetSourceValue() => _builder.MapperData.SourceObject;
16-
17-
public Expression GetSourceValues() => _builder.SourceValue;
13+
public Expression GetSourceValues() => SourceValue;
1814

1915
public Expression GetSourceCountAccess()
2016
{
21-
if (_builder.SourceTypeHelper.IsArray)
17+
if (SourceTypeHelper.IsArray)
2218
{
23-
return Expression.Property(_builder.SourceValue, "Length");
19+
return Expression.Property(SourceValue, "Length");
2420
}
2521

26-
var countPropertyInfo = _builder
27-
.SourceTypeHelper
22+
var countPropertyInfo = SourceTypeHelper
2823
.CollectionInterfaceType
2924
.GetPublicInstanceProperty("Count");
3025

31-
return Expression.Property(_builder.SourceValue, countPropertyInfo);
26+
return Expression.Property(SourceValue, countPropertyInfo);
3227
}
3328

3429
public IPopulationLoopData GetPopulationLoopData()
3530
{
36-
if (_builder.SourceTypeHelper.HasListInterface)
31+
if (SourceTypeHelper.HasListInterface)
3732
{
38-
return new IndexedSourcePopulationLoopData(_builder);
33+
return new IndexedSourcePopulationLoopData(Builder);
3934
}
4035

41-
return new EnumerableSourcePopulationLoopData(_builder);
36+
return new EnumerableSourcePopulationLoopData(Builder);
4237
}
4338
}
4439
}

AgileMapper/ObjectPopulation/Enumerables/EnumerablePopulationBuilder.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -286,9 +286,7 @@ public void AssignTargetVariable()
286286

287287
private Expression GetTargetVariableValue()
288288
{
289-
if (TargetTypeHelper.IsArray &&
290-
!SourceTypeHelper.IsEnumerableInterface &&
291-
!MapperData.SourceObject.Type.IsDictionary())
289+
if (_sourceAdapter.UseReadOnlyTargetWrapper)
292290
{
293291
return GetCopyIntoWrapperConstruction();
294292
}

AgileMapper/ObjectPopulation/Enumerables/ISourceEnumerableAdapter.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ internal interface ISourceEnumerableAdapter
1010

1111
Expression GetSourceCountAccess();
1212

13+
bool UseReadOnlyTargetWrapper { get; }
14+
1315
IPopulationLoopData GetPopulationLoopData();
1416
}
1517
}

AgileMapper/ObjectPopulation/Enumerables/SourceElementsDictionaryAdapter.cs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,28 +3,28 @@ namespace AgileObjects.AgileMapper.ObjectPopulation.Enumerables
33
using System.Linq.Expressions;
44
using Members;
55

6-
internal class SourceElementsDictionaryAdapter : ISourceEnumerableAdapter
6+
internal class SourceElementsDictionaryAdapter : SourceEnumerableAdapterBase, ISourceEnumerableAdapter
77
{
88
private readonly DictionarySourceMember _sourceMember;
9-
private readonly EnumerablePopulationBuilder _builder;
109

1110
public SourceElementsDictionaryAdapter(
1211
DictionarySourceMember sourceMember,
1312
EnumerablePopulationBuilder builder)
13+
: base(builder)
1414
{
1515
_sourceMember = sourceMember;
16-
_builder = builder;
1716
}
1817

19-
public Expression GetSourceValue() => _builder.MapperData.SourceObject;
20-
2118
public Expression GetSourceValues()
22-
=> Expression.Property(_builder.MapperData.SourceObject, "Values");
19+
=> Expression.Property(GetSourceValue(), "Values");
2320

2421
public Expression GetSourceCountAccess()
25-
=> Expression.Property(_builder.SourceValue, "Count");
22+
=> Expression.Property(SourceValue, "Count");
23+
24+
public override bool UseReadOnlyTargetWrapper
25+
=> base.UseReadOnlyTargetWrapper && Builder.Context.ElementTypesAreSimple;
2626

2727
public IPopulationLoopData GetPopulationLoopData()
28-
=> new SourceElementsDictionaryPopulationLoopData(_sourceMember, _builder);
28+
=> new SourceElementsDictionaryPopulationLoopData(_sourceMember, Builder);
2929
}
3030
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
namespace AgileObjects.AgileMapper.ObjectPopulation.Enumerables
2+
{
3+
using System.Linq.Expressions;
4+
5+
internal abstract class SourceEnumerableAdapterBase
6+
{
7+
protected SourceEnumerableAdapterBase(EnumerablePopulationBuilder builder)
8+
{
9+
Builder = builder;
10+
}
11+
12+
protected EnumerablePopulationBuilder Builder { get; }
13+
14+
protected EnumerableTypeHelper SourceTypeHelper => Builder.SourceTypeHelper;
15+
16+
protected Expression SourceValue => Builder.SourceValue;
17+
18+
protected EnumerableTypeHelper TargetTypeHelper => Builder.TargetTypeHelper;
19+
20+
public virtual Expression GetSourceValue() => Builder.MapperData.SourceObject;
21+
22+
public virtual bool UseReadOnlyTargetWrapper =>
23+
Builder.TargetTypeHelper.IsArray && !Builder.SourceTypeHelper.IsEnumerableInterface;
24+
}
25+
}

AgileMapper/ObjectPopulation/Enumerables/SourceInstanceDictionaryAdapter.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,15 @@ namespace AgileObjects.AgileMapper.ObjectPopulation.Enumerables
88
using Extensions;
99
using Members;
1010

11-
internal class SourceInstanceDictionaryAdapter : ISourceEnumerableAdapter
11+
internal class SourceInstanceDictionaryAdapter : SourceEnumerableAdapterBase, ISourceEnumerableAdapter
1212
{
1313
private readonly DictionarySourceMember _sourceMember;
1414
private readonly DefaultSourceEnumerableAdapter _defaultAdapter;
1515

1616
public SourceInstanceDictionaryAdapter(
1717
DictionarySourceMember sourceMember,
1818
EnumerablePopulationBuilder builder)
19+
: base(builder)
1920
{
2021
_sourceMember = sourceMember;
2122
_defaultAdapter = new DefaultSourceEnumerableAdapter(builder);
@@ -24,7 +25,7 @@ public SourceInstanceDictionaryAdapter(
2425

2526
public DictionaryEntryVariablePair DictionaryVariables { get; }
2627

27-
public Expression GetSourceValue()
28+
public override Expression GetSourceValue()
2829
{
2930
var emptyTarget = _sourceMember.EntryType.GetEmptyInstanceCreation();
3031
var returnLabel = Expression.Label(emptyTarget.Type, "Return");

AgileMapper/ObjectPopulation/Enumerables/SourceObjectDictionaryAdapter.cs

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,24 +10,23 @@ namespace AgileObjects.AgileMapper.ObjectPopulation.Enumerables
1010
using Members;
1111
using NetStandardPolyfills;
1212

13-
internal class SourceObjectDictionaryAdapter : ISourceEnumerableAdapter
13+
internal class SourceObjectDictionaryAdapter : SourceEnumerableAdapterBase, ISourceEnumerableAdapter
1414
{
15-
private readonly EnumerablePopulationBuilder _builder;
1615
private readonly SourceInstanceDictionaryAdapter _instanceDictionaryAdapter;
1716
private readonly Expression _emptyTarget;
1817

1918
public SourceObjectDictionaryAdapter(
2019
DictionarySourceMember sourceMember,
2120
EnumerablePopulationBuilder builder)
21+
: base(builder)
2222
{
23-
_builder = builder;
2423
_instanceDictionaryAdapter = new SourceInstanceDictionaryAdapter(sourceMember, builder);
2524

2625
var targetEnumerableType = builder.TargetTypeHelper.EnumerableInterfaceType;
2726
_emptyTarget = targetEnumerableType.GetEmptyInstanceCreation();
2827
}
2928

30-
public Expression GetSourceValue()
29+
public override Expression GetSourceValue()
3130
{
3231
var returnLabel = Expression.Label(_emptyTarget.Type, "Return");
3332
var returnEmpty = Expression.Return(returnLabel, _emptyTarget);
@@ -98,20 +97,20 @@ private Expression GetEntryValueProjection(
9897
var typedCastMethod = linqCastMethod.MakeGenericMethod(typeof(object));
9998
var linqCastCall = Expression.Call(null, typedCastMethod, untypedEnumerableVariable);
10099

101-
var sourceItemsProjection = _builder.Context.ElementTypesAreSimple
102-
? _builder.GetSourceItemsProjection(linqCastCall, GetSourceElementConversion)
103-
: _builder.GetSourceItemsProjection(linqCastCall, GetSourceElementMapping);
100+
var sourceItemsProjection = Builder.Context.ElementTypesAreSimple
101+
? Builder.GetSourceItemsProjection(linqCastCall, GetSourceElementConversion)
102+
: Builder.GetSourceItemsProjection(linqCastCall, GetSourceElementMapping);
104103

105104
var returnProjectionResult = Expression.Label(returnLabel, sourceItemsProjection);
106105

107106
return returnProjectionResult;
108107
}
109108

110109
private Expression GetSourceElementConversion(Expression sourceParameter)
111-
=> _builder.GetSimpleElementConversion(sourceParameter);
110+
=> Builder.GetSimpleElementConversion(sourceParameter);
112111

113112
private Expression GetSourceElementMapping(Expression sourceParameter, Expression counter)
114-
=> _builder.MapperData.GetMapCall(sourceParameter);
113+
=> Builder.MapperData.GetMapCall(sourceParameter);
115114

116115
#region ExcludeFromCodeCoverage
117116
#if !NET_STANDARD
@@ -129,12 +128,15 @@ public Expression GetSourceValues()
129128

130129
public Expression GetSourceCountAccess() => _instanceDictionaryAdapter.GetSourceCountAccess();
131130

131+
public override bool UseReadOnlyTargetWrapper
132+
=> base.UseReadOnlyTargetWrapper && Builder.Context.ElementTypesAreSimple;
133+
132134
public IPopulationLoopData GetPopulationLoopData()
133135
{
134136
return new SourceObjectDictionaryPopulationLoopData(
135137
_emptyTarget,
136138
_instanceDictionaryAdapter.DictionaryVariables,
137-
_builder);
139+
Builder);
138140
}
139141
}
140142
}

0 commit comments

Comments
 (0)