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); }
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); }
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); }
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); }