in tools/AutoMapper/Execution/TypeMapPlanBuilder.cs [473:545]
private Expression BuildValueResolverFunc(PropertyMap propertyMap, Expression destValueExpr)
{
Expression valueResolverFunc;
var destinationPropertyType = propertyMap.DestinationPropertyType;
var valueResolverConfig = propertyMap.ValueResolverConfig;
var typeMap = propertyMap.TypeMap;
if (valueResolverConfig != null)
{
valueResolverFunc = ToType(BuildResolveCall(destValueExpr, valueResolverConfig),
destinationPropertyType);
}
else if (propertyMap.CustomResolver != null)
{
valueResolverFunc =
propertyMap.CustomResolver.ConvertReplaceParameters(Source, _destination, destValueExpr, Context);
}
else if (propertyMap.CustomExpression != null)
{
var nullCheckedExpression = propertyMap.CustomExpression.ReplaceParameters(Source)
.NullCheck(destinationPropertyType);
var destinationNullable = destinationPropertyType.IsNullableType();
var returnType = destinationNullable && destinationPropertyType.GetTypeOfNullable() ==
nullCheckedExpression.Type
? destinationPropertyType
: nullCheckedExpression.Type;
valueResolverFunc =
TryCatch(
ToType(nullCheckedExpression, returnType),
Catch(typeof(NullReferenceException), Default(returnType)),
Catch(typeof(ArgumentNullException), Default(returnType))
);
}
else if (propertyMap.SourceMembers.Any()
&& propertyMap.SourceType != null
)
{
var last = propertyMap.SourceMembers.Last();
if (last is PropertyInfo pi && pi.GetGetMethod(true) == null)
{
valueResolverFunc = Default(last.GetMemberType());
}
else
{
valueResolverFunc = Chain(propertyMap.SourceMembers, destinationPropertyType);
}
}
else if (propertyMap.SourceMember != null)
{
valueResolverFunc = MakeMemberAccess(Source, propertyMap.SourceMember);
}
else
{
valueResolverFunc = Throw(Constant(new Exception("I done blowed up")));
}
if (propertyMap.NullSubstitute != null)
{
var nullSubstitute = Constant(propertyMap.NullSubstitute);
valueResolverFunc = Coalesce(valueResolverFunc, ToType(nullSubstitute, valueResolverFunc.Type));
}
else if (!typeMap.Profile.AllowNullDestinationValues)
{
var toCreate = propertyMap.SourceType ?? destinationPropertyType;
if (!toCreate.IsAbstract() && toCreate.IsClass())
valueResolverFunc = Coalesce(
valueResolverFunc,
ToType(DelegateFactory.GenerateNonNullConstructorExpression(toCreate), propertyMap.SourceType)
);
}
return valueResolverFunc;
}