/// <summary> /// /// </summary> /// <typeparam name="T"></typeparam> /// <typeparam name="TKey"></typeparam> /// <param name="engine"></param> /// <param name="name"></param> /// <param name="oldModel"></param> /// <param name="newModel"></param> /// <param name="selector"></param> /// <param name="defaultKey"></param> /// <returns></returns> public static IEnumerable <Difference> CompareIEnumerableWithKeyAndDefault <T, TKey>(IComparerEngine engine, string name, IEnumerable <T> oldModel, IEnumerable <T> newModel, Func <T, TKey> selector, TKey defaultKey) where T : class { var changes = new List <Difference>(); var comparer = engine.Get <T>(); var oldList = oldModel.EmptyIfNull().ToList(); var newList = newModel.EmptyIfNull().ToList(); var oldModelWithDefaultKey = oldList.Where(x => selector(x).Equals(defaultKey)).ToList(); var newModelWithDefaultKey = newList.Where(x => selector(x).Equals(defaultKey)).ToList(); var oldDict = oldList.Except(oldModelWithDefaultKey).ToDictionary(selector); var newDict = newList.Except(newModelWithDefaultKey).ToDictionary(selector); changes.AddRange(DeepCompareIDictionary(engine, name, oldDict, newDict)); var counter = 1; Func <Difference, int, Difference> updateName = (x, y) => { var id = $"{{New {y}}}"; x.Name = $"{name}.{id}.{x.Name}"; return(x); }; foreach (var model in newModelWithDefaultKey) { changes.AddRange(comparer(null, model).Select(y => updateName(y, counter))); counter++; } return(changes); }
/// <summary> /// Compares two IDictionary by doing a deep object comparison and returns the list of /// updated/added/removed values from the dictionary /// </summary> /// <typeparam name="TKey">Type of the IDictionary key</typeparam> /// <typeparam name="TValue">Type of the IDictionary value</typeparam> /// <param name="engine"></param> /// <param name="name">Name of the member</param> /// <param name="oldModel">The dictionary of values from the old model</param> /// <param name="newModel">The dictionary of updated values from the new model</param> /// <returns>A list of values that have been updated, added or removed from the dictionary</returns> public static IEnumerable <Difference> DeepCompareIDictionary <TKey, TValue>(IComparerEngine engine, string name, IDictionary <TKey, TValue> oldModel, IDictionary <TKey, TValue> newModel) where TValue : class { var comparer = engine.Get <TValue>(); var oldHash = new HashSet <TKey>(oldModel.EmptyIfNull().Keys); var newHash = new HashSet <TKey>(newModel.EmptyIfNull().Keys); foreach (var key in oldHash.Intersect(newHash)) { foreach (var update in comparer(oldModel[key], newModel[key])) { update.Name = $"{name}.{key}.{update.Name}"; yield return(update); } } foreach (var key in newHash.Except(oldHash)) { foreach (var update in comparer(null, newModel[key])) { update.Name = $"{name}.{key}.{update.Name}"; update.OldValue = null; yield return(update); } } foreach (var key in oldHash.Except(newHash)) { foreach (var update in comparer(oldModel[key], null)) { update.Name = $"{name}.{key}.{update.Name}"; update.NewValue = null; yield return(update); } } }