Пример #1
0
        public static object Adapt(TSource source, object destination, Dictionary <int, int> parameterIndexs)
        {
            if (source == null)
            {
                return(null);
            }

            #region Check MaxDepth

            var config    = TypeAdapterConfig <TSource, TDestination> .Configuration;
            var hasConfig = config != null;

            var hasMaxDepth = hasConfig && config.MaxDepth > 0;

            if (hasMaxDepth)
            {
                if (parameterIndexs == null)
                {
                    parameterIndexs = new Dictionary <int, int>();
                }

                var hashCode = typeof(TSource).GetHashCode() + typeof(TDestination).GetHashCode();

                if (parameterIndexs.ContainsKey(hashCode))
                {
                    parameterIndexs[hashCode] = parameterIndexs[hashCode] + 1;

                    if (parameterIndexs[hashCode] >= config.MaxDepth)
                    {
                        return(null);
                    }
                }
                else
                {
                    parameterIndexs.Add(hashCode, 1);
                }
            }

            #endregion

            var collectionAdapterModel = _collectionAdapterModel;

            var destinationType = typeof(TDestination);

            if (destinationType.IsArray)
            {
                #region CopyToArray

                byte i = 0;
                var  adapterInvoker = collectionAdapterModel.AdaptInvoker;
                var  array          = destination == null
                    ? new TDestinationElementType[((ICollection)source).Count]
                    : (TDestinationElementType[])destination;
                if (collectionAdapterModel.IsPrimitive)
                {
                    var hasInvoker = adapterInvoker != null;
                    foreach (var item in source)
                    {
                        if (item == null)
                        {
                            array.SetValue(default(TDestinationElementType), i);
                        }
                        if (hasInvoker)
                        {
                            array.SetValue(adapterInvoker(null, new[] { item }), i);
                        }
                        else
                        {
                            array.SetValue(item, i);
                        }
                        i++;
                    }
                }
                else
                {
                    foreach (var item in source)
                    {
                        array.SetValue(
                            adapterInvoker(null,
                                           new[] { item, hasMaxDepth ? ReflectionUtils.Clone(parameterIndexs) : parameterIndexs }),
                            i);
                        i++;
                    }
                }

                return(array);

                #endregion
            }

            if (destinationType.IsGenericType)
            {
                #region CopyToList

                var adapterInvoker = collectionAdapterModel.AdaptInvoker;
                var list           = destination == null
                    ? new List <TDestinationElementType>()
                    : (List <TDestinationElementType>)destination;
                if (collectionAdapterModel.IsPrimitive)
                {
                    var hasInvoker = adapterInvoker != null;
                    foreach (var item in source)
                    {
                        if (item == null)
                        {
                            list.Add(default(TDestinationElementType));
                        }
                        else if (hasInvoker)
                        {
                            list.Add((TDestinationElementType)adapterInvoker(null, new[] { item }));
                        }
                        else
                        {
                            list.Add((TDestinationElementType)item);
                        }
                    }
                }
                else
                {
                    foreach (var item in source)
                    {
                        list.Add((TDestinationElementType)adapterInvoker(null,
                                                                         new[] { item, hasMaxDepth ? ReflectionUtils.Clone(parameterIndexs) : parameterIndexs }));
                    }
                }

                return(list);

                #endregion
            }

            if (destinationType == typeof(ArrayList))
            {
                #region CopyToArrayList

                var adapterInvoker = collectionAdapterModel.AdaptInvoker;
                var array          = destination == null ? new ArrayList() : (ArrayList)destination;
                if (collectionAdapterModel.IsPrimitive)
                {
                    var hasInvoker = adapterInvoker != null;
                    foreach (var item in source)
                    {
                        if (item == null)
                        {
                            array.Add(default(TDestinationElementType));
                        }
                        else if (hasInvoker)
                        {
                            array.Add(adapterInvoker(null, new[] { item }));
                        }
                        else
                        {
                            array.Add(item);
                        }
                    }
                }
                else
                {
                    foreach (var item in source)
                    {
                        array.Add(adapterInvoker(null,
                                                 new[] { item, hasMaxDepth ? ReflectionUtils.Clone(parameterIndexs) : parameterIndexs }));
                    }
                }

                return(array);

                #endregion
            }

            return((TDestination)destination);
        }
Пример #2
0
        public static TDestination Adapt(TSource source, TDestination destination, bool isNew,
                                         Dictionary <int, int> parameterIndexs)
        {
            if (source == null)
            {
                return(null);
            }

            var config = TypeAdapterConfig <TSource, TDestination> .Configuration;

            var hasConfig = config != null;

            var hasMaxDepth = hasConfig && config.MaxDepth > 0;

            #region Check MaxDepth

            if (hasMaxDepth)
            {
                if (parameterIndexs == null)
                {
                    parameterIndexs = new Dictionary <int, int>();
                }

                var hashCode = typeof(TSource).GetHashCode() + typeof(TDestination).GetHashCode();

                if (parameterIndexs.ContainsKey(hashCode))
                {
                    var index = parameterIndexs[hashCode] + 1;

                    parameterIndexs[hashCode] = index;

                    if (index >= config.MaxDepth)
                    {
                        return(null);
                    }
                }
                else
                {
                    parameterIndexs.Add(hashCode, 1);
                }
            }

            #endregion

            if (destination == null)
            {
                destination = (TDestination)_destinationFactory();
            }

            var ignoreNullValues = isNew ||
                                   hasConfig && config.IgnoreNullValues.HasValue && config.IgnoreNullValues.Value;

            var properties = _adapterModel.Properties;
            for (var i = 0; i < properties.Length; i++)
            {
                var property = properties[i];

                switch (property.ConvertType)
                {
                case 1:     //Primitive
                    var primitiveValue = property.Getter.Invoke(source);
                    if (primitiveValue == null)
                    {
                        if (ignoreNullValues)
                        {
                            continue;
                        }
                        else
                        {
                            primitiveValue = property.DefaultDestinationValue;
                        }
                    }

                    if (property.AdaptInvoker == null)
                    {
                        property.Setter.Invoke(destination, primitiveValue);
                    }
                    else
                    {
                        property.Setter.Invoke(destination,
                                               property.AdaptInvoker(null,
                                                                     new[]
                        {
                            primitiveValue,
                            hasMaxDepth ? ReflectionUtils.Clone(parameterIndexs) : parameterIndexs
                        }));
                    }
                    break;

                case 2:     //Flattening Get Method
                    property.Setter.Invoke(destination, property.AdaptInvoker(source, null));
                    break;

                case 3:     //Flattening Deep Property
                    var    flatInvokers = property.FlatteningInvokers;
                    object value        = source;
                    for (var j = 0; j < flatInvokers.Length; j++)
                    {
                        value = flatInvokers[j](value);
                        if (value == null)
                        {
                            break;
                        }
                    }

                    if (value == null)
                    {
                        if (ignoreNullValues)
                        {
                            continue;
                        }
                        else
                        {
                            value = property.DefaultDestinationValue;
                        }
                    }

                    property.Setter.Invoke(destination, value);
                    break;

                case 4:     // Adapter
                    var sourceValue = property.Getter.Invoke(source);
                    if (sourceValue == null)
                    {
                        if (ignoreNullValues)
                        {
                            continue;
                        }
                        else
                        {
                            sourceValue = property.DefaultDestinationValue;
                        }
                    }

                    property.Setter.Invoke(destination,
                                           property.AdaptInvoker(null,
                                                                 new[]
                    {
                        sourceValue, hasMaxDepth ? ReflectionUtils.Clone(parameterIndexs) : parameterIndexs
                    }));
                    break;

                case 5:     // Custom Resolve
                    property.Setter.Invoke(destination, property.CustomResolver(source));
                    break;
                }
            }

            return(destination);
        }
Пример #3
0
        private static TDestination Adapt(TSource source, TDestination destination, bool isNew, bool evaluateMaxDepth, Dictionary <long, int> parameterIndexes)
        {
            if (source == null)
            {
                return(default(TDestination));
            }

            var configSettings = TypeAdapterConfig <TSource, TDestination> .ConfigSettings;

            bool hasConfig   = false;
            bool hasMaxDepth = false;

            if (configSettings != null)
            {
                hasConfig = true;
                if (configSettings.ConverterFactory != null)
                {
                    var converter = configSettings.ConverterFactory();
                    return(converter.Resolve(source));
                }
                int maxDepth = configSettings.MaxDepth.GetValueOrDefault();
                if (maxDepth > 0)
                {
                    hasMaxDepth = true;
                    if (MaxDepthExceeded(ref parameterIndexes, maxDepth, evaluateMaxDepth))
                    {
                        return(default(TDestination));
                    }
                }
            }

            if (destination == null)
            {
                destination = DestinationFactory();
            }

            bool ignoreNullValues = isNew || (hasConfig && configSettings.IgnoreNullValues.HasValue && configSettings.IgnoreNullValues.Value);

            PropertyModel <TSource, TDestination> propertyModel = null;

            try
            {
                var propertyModels = GetAdapterModel().Properties;

                for (int index = 0; index < propertyModels.Length; index++)
                {
                    propertyModel = propertyModels[index];

                    object destinationValue = null;

                    switch (propertyModel.ConvertType)
                    {
                    case 1:     //Primitive
                        object primitiveValue = propertyModel.Getter.Invoke(source);
                        if (primitiveValue == null)
                        {
                            continue;
                        }

                        if (propertyModel.AdaptInvoker == null)
                        {
                            destinationValue = primitiveValue;
                        }
                        else
                        {
                            destinationValue = propertyModel.AdaptInvoker(null,
                                                                          new[]
                            {
                                primitiveValue,
                                true,
                                (hasMaxDepth ? ReflectionUtils.Clone(parameterIndexes) : parameterIndexes)
                            });
                        }
                        break;

                    case 2:     //Flattening Get Method
                        destinationValue = propertyModel.AdaptInvoker(source, null);
                        break;

                    case 3:     //Flattening Deep Property
                        var    flatInvokers = propertyModel.FlatteningInvokers;
                        object value        = source;
                        foreach (GenericGetter getter in flatInvokers)
                        {
                            value = getter.Invoke(value);
                            if (value == null)
                            {
                                break;
                            }
                        }

                        if (value == null && ignoreNullValues)
                        {
                            continue;
                        }
                        destinationValue = value;
                        break;

                    case 4:     // Adapter
                        object sourceValue = propertyModel.Getter.Invoke(source);
                        if (sourceValue == null && ignoreNullValues)
                        {
                            continue;
                        }

                        destinationValue = propertyModel.AdaptInvoker(null,
                                                                      new[]
                        {
                            sourceValue,
                            true,
                            (hasMaxDepth ? ReflectionUtils.Clone(parameterIndexes) : parameterIndexes)
                        });
                        break;

                    case 5:     // Custom Resolve
                        if (propertyModel.Condition == null || propertyModel.Condition(source))
                        {
                            destinationValue = propertyModel.CustomResolver(source);
                            break;
                        }
                        continue;
                    }

                    if (propertyModel.DestinationTransform == null)
                    {
                        propertyModel.Setter.Invoke(destination, destinationValue);
                    }
                    else
                    {
                        propertyModel.Setter.Invoke(destination, propertyModel.DestinationTransform(destinationValue));
                    }
                }
            }
            catch (Exception ex)
            {
                if (ex is ArgumentOutOfRangeException)
                {
                    throw;
                }

                if (_adapterModel == null)
                {
                    throw new InvalidOperationException(_nonInitializedAdapterMessage + "\nException: " + ex);
                }

                if (propertyModel != null)
                {
                    //Todo: This slows things down with the try-catch but the information is critical in debugging
                    throw new InvalidOperationException(_propertyMappingErrorMessage + propertyModel.SetterPropertyName + "\nException: " + ex, ex);
                }
                throw;
            }

            return(destination);
        }
Пример #4
0
        public static object Adapt(TSource source, object destination, Dictionary <long, int> parameterIndexes)
        {
            if (source == null)
            {
                return(null);
            }

            #region Check MaxDepth

            var configSettings = TypeAdapterConfig <TSourceElement, TDestinationElement> .ConfigSettings;

            var hasMaxDepth = false;

            if (configSettings != null)
            {
                int maxDepth = configSettings.MaxDepth.GetValueOrDefault();
                if (maxDepth > 0)
                {
                    hasMaxDepth = true;
                    if (MaxDepthExceeded(ref parameterIndexes, maxDepth, true))
                    {
                        return(null);
                    }
                }
            }

            #endregion

            var destinationType = typeof(TDestination);

            if (destinationType.IsArray)
            {
                #region CopyToArray

                byte i = 0;
                var  adapterInvoker = _collectionAdapterModel.AdaptInvoker;
                var  array          = destination == null ? new TDestinationElement[((ICollection)source).Count] : (TDestinationElement[])destination;
                if (_collectionAdapterModel.IsPrimitive)
                {
                    bool hasInvoker = adapterInvoker != null;
                    foreach (var item in source)
                    {
                        if (item == null)
                        {
                            array.SetValue(default(TDestinationElement), i);
                        }
                        if (hasInvoker)
                        {
                            array.SetValue(adapterInvoker(null, new[] { item }), i);
                        }
                        else
                        {
                            array.SetValue(item, i);
                        }
                        i++;
                    }
                }
                else
                {
                    foreach (var item in source)
                    {
                        array.SetValue(adapterInvoker(null, new[] { item, false, (hasMaxDepth ? ReflectionUtils.Clone(parameterIndexes) : parameterIndexes) }), i);
                        i++;
                    }
                }

                return(array);

                #endregion
            }

            if (destinationType.IsGenericType)
            {
                #region CopyToList

                var adapterInvoker = _collectionAdapterModel.AdaptInvoker;
                var list           = destination == null ? new List <TDestinationElement>() : (List <TDestinationElement>)destination;
                if (_collectionAdapterModel.IsPrimitive)
                {
                    bool hasInvoker = adapterInvoker != null;
                    foreach (var item in source)
                    {
                        if (item == null)
                        {
                            list.Add(default(TDestinationElement));
                        }
                        else if (hasInvoker)
                        {
                            list.Add((TDestinationElement)adapterInvoker(null, new[] { item }));
                        }
                        else
                        {
                            list.Add((TDestinationElement)item);
                        }
                    }
                }
                else
                {
                    foreach (var item in source)
                    {
                        list.Add((TDestinationElement)adapterInvoker(null, new[] { item, false, (hasMaxDepth ? ReflectionUtils.Clone(parameterIndexes) : parameterIndexes) }));
                    }
                }

                return(list);

                #endregion
            }

            if (destinationType == typeof(ArrayList))
            {
                #region CopyToArrayList

                var adapterInvoker = _collectionAdapterModel.AdaptInvoker;
                var array          = destination == null ? new ArrayList() : (ArrayList)destination;
                if (_collectionAdapterModel.IsPrimitive)
                {
                    bool hasInvoker = adapterInvoker != null;
                    foreach (var item in source)
                    {
                        if (item == null)
                        {
                            array.Add(default(TDestinationElement));
                        }
                        else if (hasInvoker)
                        {
                            array.Add(adapterInvoker(null, new[] { item }));
                        }
                        else
                        {
                            array.Add(item);
                        }
                    }
                }
                else
                {
                    foreach (var item in source)
                    {
                        array.Add(adapterInvoker(null, new[] { item, true, (hasMaxDepth ? ReflectionUtils.Clone(parameterIndexes) : parameterIndexes) }));
                    }
                }

                return(array);

                #endregion
            }

            return((TDestination)destination);
        }