private void CompareValue(object original, object current, IMemberOptions options) { var compare = options?.Equality ?? Equals; bool areEqual = compare(original, current); if (areEqual) { return; } CreateChange(ChangeOperation.Replace, original, current); }
public static string GetHeader(this IMemberOptions options, bool useHeaderHumanizer) { if (options.IsHeader) { return(options.Header); } if (useHeaderHumanizer) { return(HeaderHumanizer.Humanize(options.MemberName)); } return(options.MemberName); }
public bool IsBackReference( ModelOptions options, TypeMap typeMap, IMemberOptions memberOptions, out BackReferenceMap backReferenceMap) { bool result = false; backReferenceMap = null; ITypeOptions memberTypeOptions = options.GetTypeOptions(memberOptions.Type); if (typeMap.Parent != null) { if (typeMap.TargetOptions.IsEntity && (typeMap.Parent.TargetOptions.Type == memberTypeOptions.Type || typeMap.Parent.TargetOptions.Type == memberTypeOptions.ItemType)) { backReferenceMap = new BackReferenceMap { MemberOptions = memberOptions, MemberTypeOptions = options.GetTypeOptions(memberOptions.Type), Parent = typeMap.Parent }; result = true; } else if (typeMap.Parent.Parent != null && typeMap.Parent.TargetOptions.IsCollection && (typeMap.Parent.Parent.TargetOptions.Type == memberTypeOptions.Type || typeMap.Parent.Parent.TargetOptions.Type == memberTypeOptions.ItemType)) { backReferenceMap = new BackReferenceMap { MemberOptions = memberOptions, MemberTypeOptions = options.GetTypeOptions(memberOptions.Type), Parent = typeMap.Parent.Parent }; result = true; } } return(result); }
private void CompareByEquality(IEnumerable original, IEnumerable current, IMemberOptions options) { var originalList = original?.Cast <object>().ToList() ?? new List <object>(); var currentList = current?.Cast <object>().ToList() ?? new List <object>(); var currentPath = CurrentPath(); var currentName = CurrentName(); var compare = options?.Equality ?? Equals; _pathStack.Pop(); for (int index = 0; index < currentList.Count; index++) { string p = $"{currentPath}[{index}]"; var v = currentList[index]; var o = originalList.FirstOrDefault(f => compare(f, v)); if (o == null) { // added item CreateChange(ChangeOperation.Add, null, v, p, currentName); continue; } // remove so can't be reused originalList.Remove(o); var t = o.GetType(); _pathStack.Push(p); CompareType(t, o, v, options); _pathStack.Pop(); } _pathStack.Push(currentPath); // removed items foreach (var v in originalList) { CreateChange(ChangeOperation.Remove, v, null); } }
private void CompareList(object original, object current, IMemberOptions options) { var originalList = original as IList; var currentList = current as IList; // both null, nothing to compare if (originalList == null && currentList == null) { return; } if (options?.CollectionComparison == CollectionComparison.ObjectEquality) { CompareByEquality(originalList, currentList, options); } else { CompareByIndexer(originalList, currentList, t => t.Count, (t, i) => t[i]); } }
private void CompareArray(object original, object current, IMemberOptions options) { var originalArray = original as Array; var currentArray = current as Array; // both null, nothing to compare if (originalArray == null && currentArray == null) { return; } if (options?.CollectionComparison == CollectionComparison.ObjectEquality) { CompareByEquality(originalArray, currentArray, options); } else { CompareByIndexer(originalArray, currentArray, t => t.Length, (t, i) => t.GetValue(i)); } }
private void CompareType(Type type, object original, object current, IMemberOptions options = null) { // both null, nothing to compare if (original == null && current == null) { return; } Type keyType; Type elementType; if (type.IsArray) { CompareArray(original, current, options); } else if (original is IDictionary || current is IDictionary) { CompareDictionary(original, current); } else if (type.IsDictionary(out keyType, out elementType)) { CompareGenericDictionary(original, current, keyType, elementType); } else if (original is IList || current is IList) { CompareList(original, current, options); } else if (type.IsCollection()) { CompareCollection(original, current, options); } else if (type.GetTypeInfo().IsValueType || type == typeof(string)) { CompareValue(original, current, options); } else { CompareObject(type, original, current); } }
private void CompareCollection(object original, object current, IMemberOptions options) { var originalEnumerable = original as IEnumerable; var currentEnumerable = current as IEnumerable; // both null, nothing to compare if (originalEnumerable == null && currentEnumerable == null) { return; } if (options?.CollectionComparison == CollectionComparison.ObjectEquality) { CompareByEquality(originalEnumerable, currentEnumerable, options); return; } // convert to object array var originalArray = originalEnumerable?.Cast <object>().ToArray(); var currentArray = currentEnumerable?.Cast <object>().ToArray(); CompareByIndexer(originalArray, currentArray, t => t.Length, (t, i) => t.GetValue(i)); }
public TypeMap Create(Mapper mapper, ModelOptions options, TypeMap parentMap, Type sourceType, Type targetType, bool owned) { TypeMap typeMap = new TypeMap(); typeMap.Parent = parentMap; typeMap.Mapper = mapper; typeMap.SourceOptions = options.GetTypeOptions(sourceType); typeMap.Source = Parameter(sourceType, "source_" + sourceType.Name); typeMap.TargetOptions = options.GetTypeOptions(targetType); typeMap.Target = Parameter(targetType, "target_" + targetType.Name); typeMap.Owned = owned; if (parentMap == null) { typeMap.Context = Parameter(typeof(IMapperContext), "context"); } else { typeMap.Context = parentMap.Context; } while (parentMap != null) { if (typeMap.TargetOptions == parentMap.TargetOptions && typeMap.SourceOptions == parentMap.SourceOptions && typeMap.Owned == parentMap.Owned) { return(parentMap); } parentMap = parentMap.Parent; } if (typeMap.TargetOptions.IsCollection) { Type sourceItemType = typeMap.SourceOptions.ItemType; Type targetItemType = typeMap.TargetOptions.ItemType; if (typeMap.SourceOptions.Type == typeof(object)) { sourceItemType = typeof(object); } typeMap.ItemMap = Create(mapper, options, typeMap, sourceItemType, targetItemType, owned); } else if (typeMap.TargetOptions.IsComplexType) { IEnumerable <string> memberNames = typeMap.TargetOptions.MemberNames; if (memberNames != null) { foreach (string memberName in memberNames) { IMemberOptions targetMemberOptions = typeMap.TargetOptions.GetMember(memberName); if (targetMemberOptions != null && targetMemberOptions.CanWrite && !targetMemberOptions.Ignored) { if (IsBackReference(options, typeMap, targetMemberOptions, out BackReferenceMap backRefMap)) { typeMap.BackReference = backRefMap; } else { IMemberOptions sourceMemberOptions = typeMap.SourceOptions.GetMember(memberName); if (sourceMemberOptions != null && sourceMemberOptions.CanRead && !sourceMemberOptions.Ignored) { MemberMap memberMap = new MemberMap(); memberMap.SourceOptions = sourceMemberOptions; memberMap.TargetOptions = targetMemberOptions; memberMap.TypeMap = Create( mapper, options, typeMap, memberMap.SourceOptions.Type, memberMap.TargetOptions.Type, targetMemberOptions.Owned); typeMap.Members.Add(memberMap); } } } } } } return(typeMap); }