private Expression CreateMapperFunc(Expression assignmentFunc)
{
var mapperFunc = assignmentFunc;
if(_typeMap.Condition != null)
{
mapperFunc =
Condition(_typeMap.Condition.Body,
mapperFunc, Default(_typeMap.DestinationTypeToUse));
//mapperFunc = (source, context, destFunc) => _condition(context) ? inner(source, context, destFunc) : default(TDestination);
}
if(_typeMap.MaxDepth > 0)
{
mapperFunc = Condition(
LessThanOrEqual(
Call(_context, ((MethodCallExpression)GetTypeDepthInfo.Body).Method, Constant(_typeMap.Types)),
Constant(_typeMap.MaxDepth)
),
mapperFunc,
Default(_typeMap.DestinationTypeToUse));
//mapperFunc = (source, context, destFunc) => context.GetTypeDepth(types) <= maxDepth ? inner(source, context, destFunc) : default(TDestination);
}
if(_typeMap.Profile.AllowNullDestinationValues && !_typeMap.SourceType.IsValueType())
{
mapperFunc =
Condition(Equal(_source, Default(_typeMap.SourceType)),
Default(_typeMap.DestinationTypeToUse), mapperFunc.RemoveIfNotNull(_source));
//mapperFunc = (source, context, destFunc) => source == default(TSource) ? default(TDestination) : inner(source, context, destFunc);
}
if(_typeMap.PreserveReferences)
{
var cache = Variable(_typeMap.DestinationTypeToUse, "cachedDestination");
var condition = Condition(
AndAlso(
NotEqual(_source, Constant(null)),
Call(Property(_context, "InstanceCache"), typeof(Dictionary<object, object>).GetDeclaredMethod("ContainsKey"), _source)),
Assign(cache,
ToType(Property(Property(_context, "InstanceCache"), "Item", _source), _typeMap.DestinationTypeToUse)),
Assign(cache, mapperFunc)
);
mapperFunc = Block(new[] { cache }, condition, cache);
}
return mapperFunc;
}