AutoMapper.Execution.TypeMapPlanBuilder.CreatePropertyMapFunc C# (CSharp) Method

CreatePropertyMapFunc() private method

private CreatePropertyMapFunc ( PropertyMap propertyMap ) : Expression
propertyMap PropertyMap
return System.Linq.Expressions.Expression
        private Expression CreatePropertyMapFunc(PropertyMap propertyMap)
        {
            var destMember = MakeMemberAccess(_destination, propertyMap.DestinationProperty);

            Expression getter;

            var pi = propertyMap.DestinationProperty as PropertyInfo;
            if(pi != null && pi.GetGetMethod(true) == null)
            {
                getter = Default(propertyMap.DestinationPropertyType);
            }
            else
            {
                getter = destMember;
            }

            Expression destValueExpr;
            if(propertyMap.UseDestinationValue)
            {
                destValueExpr = getter;
            }
            else
            {
                if(_initialDestination.Type.IsValueType())
                {
                    destValueExpr = Default(propertyMap.DestinationPropertyType);
                }
                else
                {
                    destValueExpr = Condition(Equal(_initialDestination, Constant(null)), Default(propertyMap.DestinationPropertyType), getter);
                }
            }

            var valueResolverExpr = BuildValueResolverFunc(propertyMap, getter);
            var resolvedValue = Variable(valueResolverExpr.Type, "resolvedValue");
            var setResolvedValue = Assign(resolvedValue, valueResolverExpr);
            valueResolverExpr = resolvedValue;

            if(propertyMap.DestinationPropertyType != null)
            {
                var typePair = new TypePair(valueResolverExpr.Type, propertyMap.DestinationPropertyType);
                valueResolverExpr = MapExpression(typePair, valueResolverExpr, propertyMap, destValueExpr);
            }
            else
            {
                valueResolverExpr = SetMap(propertyMap, valueResolverExpr, destValueExpr);
            }

            ParameterExpression propertyValue;
            Expression setPropertyValue;
            if(valueResolverExpr == resolvedValue)
            {
                propertyValue = resolvedValue;
                setPropertyValue = setResolvedValue;
            }
            else
            {
                propertyValue = Variable(valueResolverExpr.Type, "propertyValue");
                setPropertyValue = Assign(propertyValue, valueResolverExpr);
            }

            Expression mapperExpr;
            if(propertyMap.DestinationProperty is FieldInfo)
            {
                mapperExpr = propertyMap.SourceType != propertyMap.DestinationPropertyType
                    ? Assign(destMember, ToType(propertyValue, propertyMap.DestinationPropertyType))
                    : Assign(getter, propertyValue);
            }
            else
            {
                var setter = ((PropertyInfo)propertyMap.DestinationProperty).GetSetMethod(true);
                if(setter == null)
                {
                    mapperExpr = propertyValue;
                }
                else
                {
                    mapperExpr = Assign(destMember, ToType(propertyValue, propertyMap.DestinationPropertyType));
                }
            }

            if(propertyMap.Condition != null)
            {
                mapperExpr = IfThen(
                    propertyMap.Condition.ConvertReplaceParameters(
                        _source,
                        _destination,
                        ToType(propertyValue, propertyMap.Condition.Parameters[2].Type),
                        ToType(getter, propertyMap.Condition.Parameters[2].Type),
                        _context
                        ),
                    mapperExpr
                    );
            }

            mapperExpr = Block(new[] { setResolvedValue, setPropertyValue, mapperExpr }.Distinct());

            if(propertyMap.PreCondition != null)
            {
                mapperExpr = IfThen(
                    propertyMap.PreCondition.ConvertReplaceParameters(_source, _context),
                    mapperExpr
                    );
            }

            return Block(new[] { resolvedValue, propertyValue }.Distinct(), mapperExpr);
        }