@@ -2,11 +2,12 @@ namespace AgileObjects.AgileMapper.ObjectPopulation
22{
33 using System ;
44 using System . Collections . Generic ;
5+ using System . Linq ;
56 using System . Linq . Expressions ;
7+ using Extensions ;
68#if NET_STANDARD
79 using System . Reflection ;
810#endif
9- using Configuration ;
1011 using Members ;
1112 using NetStandardPolyfills ;
1213 using ReadableExpressions ;
@@ -32,13 +33,12 @@ public Expression Create(IObjectMappingData mappingData)
3233 var basicMapperData = mapperData . WithNoTargetMember ( ) ;
3334
3435 mappingExpressions . AddRange ( GetShortCircuitReturns ( returnNull , mapperData ) ) ;
35- mappingExpressions . Add ( GetTypeTests ( mappingData ) ) ;
36- mappingExpressions . Add ( GetMappingCallback ( CallbackPosition . Before , basicMapperData , mapperData ) ) ;
37- mappingExpressions . AddRange ( GetObjectPopulation ( mappingData ) ) ;
38- mappingExpressions . Add ( GetMappingCallback ( CallbackPosition . After , basicMapperData , mapperData ) ) ;
39- mappingExpressions . Add ( Expression . Label ( mapperData . ReturnLabelTarget , GetReturnValue ( mapperData ) ) ) ;
36+ mappingExpressions . AddUnlessNullOrEmpty ( GetTypeTests ( mappingData ) ) ;
37+ mappingExpressions . AddUnlessNullOrEmpty ( GetMappingCallbackOrNull ( CallbackPosition . Before , basicMapperData , mapperData ) ) ;
38+ mappingExpressions . AddRange ( GetObjectPopulation ( mappingData ) . WhereNotNull ( ) ) ;
39+ mappingExpressions . AddUnlessNullOrEmpty ( GetMappingCallbackOrNull ( CallbackPosition . After , basicMapperData , mapperData ) ) ;
4040
41- var mappingBlock = Expression . Block ( new [ ] { mapperData . InstanceVariable } , mappingExpressions ) ;
41+ var mappingBlock = GetMappingBlock ( mappingExpressions . WhereNotNull ( ) . ToList ( ) , mapperData ) ;
4242 var mappingBlockWithTryCatch = WrapInTryCatch ( mappingBlock , mapperData ) ;
4343
4444 return mappingBlockWithTryCatch ;
@@ -56,21 +56,50 @@ protected abstract IEnumerable<Expression> GetShortCircuitReturns(
5656
5757 protected abstract Expression GetTypeTests ( IObjectMappingData mappingData ) ;
5858
59- private static Expression GetMappingCallback (
59+ protected static Expression GetMappingCallbackOrNull (
6060 CallbackPosition callbackPosition ,
6161 IBasicMapperData basicData ,
6262 IMemberMapperData mapperData )
6363 {
64- return GetCallbackOrEmpty ( c => c . GetCallbackOrNull ( callbackPosition , basicData , mapperData ) , mapperData ) ;
64+ return mapperData . MapperContext . UserConfigurations . GetCallbackOrNull ( callbackPosition , basicData , mapperData ) ;
6565 }
6666
67- protected static Expression GetCallbackOrEmpty (
68- Func < UserConfigurationSet , Expression > callbackFactory ,
69- IMemberMapperData mapperData )
70- => callbackFactory . Invoke ( mapperData . MapperContext . UserConfigurations ) ?? Constants . EmptyExpression ;
71-
7267 protected abstract IEnumerable < Expression > GetObjectPopulation ( IObjectMappingData mappingData ) ;
7368
69+ private Expression GetMappingBlock ( IList < Expression > mappingExpressions , ObjectMapperData mapperData )
70+ {
71+ if ( mappingExpressions [ 0 ] . NodeType != ExpressionType . Block )
72+ {
73+ var objectAssignment = mappingExpressions . First ( exp => exp . NodeType == ExpressionType . Assign ) ;
74+
75+ if ( mappingExpressions . Last ( ) == objectAssignment )
76+ {
77+ var assignment = ( BinaryExpression ) objectAssignment ;
78+ var assignedValue = assignment . Right ;
79+
80+ if ( assignedValue . NodeType == ExpressionType . Invoke )
81+ {
82+ assignedValue = assignedValue . Replace ( mapperData . InstanceVariable , mapperData . TargetObject ) ;
83+ }
84+
85+ if ( mappingExpressions . Count == 1 )
86+ {
87+ return Expression . Block ( assignedValue ) ;
88+ }
89+
90+ mappingExpressions [ mappingExpressions . Count - 1 ] = assignedValue ;
91+
92+ return Expression . Block ( mappingExpressions ) ;
93+ }
94+ }
95+
96+ mappingExpressions . Add ( Expression . Label ( mapperData . ReturnLabelTarget , GetReturnValue ( mapperData ) ) ) ;
97+
98+ var mappingBlock = Expression . Block ( new [ ] { mapperData . InstanceVariable } , mappingExpressions ) ;
99+
100+ return mappingBlock ;
101+ }
102+
74103 protected abstract Expression GetReturnValue ( ObjectMapperData mapperData ) ;
75104
76105 private static Expression WrapInTryCatch ( Expression mappingBlock , IMemberMapperData mapperData )
0 commit comments