/// <summary> /// Copies all dynamic properties from an instance to another instance. /// </summary> /// <param name="fromInstance">The instance to copy the shadow attributes from</param> /// <param name="toInstance">The instance to copy the shadow attributes to</param> public static void CopyDynamicProperties(object fromInstance, object toInstance) { if (fromInstance == null) { throw new ArgumentNullException(nameof(fromInstance)); } if (toInstance == null) { throw new ArgumentNullException(nameof(toInstance)); } var type = fromInstance.GetType().GetTypeInfo(); bool forceShadowCreation = IdentifiableHelper.IsIdentifiable(type); ShadowContainer shadow; if (forceShadowCreation) { shadow = Shadows.GetValue(fromInstance, callback => new ShadowContainer(fromInstance.GetType())); } else { Shadows.TryGetValue(fromInstance, out shadow); } if (shadow != null) { var newShadow = Shadows.GetValue(toInstance, key => new ShadowContainer()); shadow.CopyTo(newShadow); newShadow.SetId(toInstance, shadow.GetId(fromInstance)); } }
/// <summary> /// Copies all dynamic properties from an instance to another instance. /// </summary> /// <param name="fromInstance">The instance to copy the shadow attributes from</param> /// <param name="toInstance">The instance to copy the shadow attributes to</param> public static void Copy(object fromInstance, object toInstance) { if (!Enable) { return; } if (fromInstance == null) { throw new ArgumentNullException(nameof(fromInstance)); } if (toInstance == null) { throw new ArgumentNullException(nameof(toInstance)); } var type = fromInstance.GetType(); // If the type is identifiable, we need to force the creation of a ShadowObject in order to // generate an id bool forceShadowCreation = IdentifiableHelper.IsIdentifiable(type); ShadowObject shadow; if (forceShadowCreation) { shadow = Shadows.GetValue(fromInstance, callback => new ShadowObject(fromInstance.GetType())); } else { Shadows.TryGetValue(fromInstance, out shadow); } if (shadow != null) { var newShadow = Shadows.GetValue(toInstance, key => new ShadowObject()); shadow.CopyTo(newShadow); // Copy the id of the attached reference to the destination if (shadow.IsIdentifiable) { newShadow.SetId(toInstance, shadow.GetId(fromInstance)); } } }
private ShadowObject(Type type) { isIdentifiable = IdentifiableHelper.IsIdentifiable(type); }
/// <summary> /// Find all the member path in the <paramref name="dual"/> object corresponding to this path in <paramref name="reference"/> object. /// </summary> /// <param name="reference">The reference root element</param> /// <param name="dual">The dual root element</param> /// <returns><value>True</value> if a corresponding path could be found, <value>False</value> otherwise</returns> public IEnumerable <MemberPath> Resolve(object reference, object dual) { if (reference == null) { throw new ArgumentNullException("reference"); } if (dual == null) { throw new ArgumentNullException("dual"); } if (items.Count == 0) { return(Enumerable.Empty <MemberPath>()); } var dualPaths = new List <MemberPath> { new MemberPath() }; for (var i = 0; i < items.Count; i++) { var referenceItem = items[i]; var nextReference = reference; for (var j = 0; j < i; ++j) { nextReference = items[j].GetValue(nextReference); } var dualsCount = dualPaths.Count; for (var c = 0; c < dualsCount; ++c) { var dualPath = dualPaths[c]; var nextDual = dual; for (var j = 0; j < i; ++j) { nextDual = dualPath.items[j].GetValue(nextDual); } if (referenceItem is ArrayPathItem || referenceItem is CollectionPathItem) { dualPaths.RemoveAt(c--); --dualsCount; try { nextReference = referenceItem.GetValue(nextReference); // id is set on element itself Guid referenceId; if (!IdentifiableHelper.TryGetId(nextReference, out referenceId)) { continue; } for (var k = 0; k < Int32.MaxValue; ++k) { var dualItem = (referenceItem is ArrayPathItem) ? (MemberPathItem) new ArrayPathItem(k) : new CollectionPathItem(((CollectionPathItem)referenceItem).Descriptor, k); dualItem.Parent = dualPath.items.LastOrDefault(); Guid dualId; var dualElt = dualItem.GetValue(nextDual); if (IdentifiableHelper.TryGetId(dualElt, out dualId) && referenceId == dualId) { var path = dualPath.Clone(); path.AddItem(dualItem); dualPaths.Add(path); } } } catch (Exception) { } } else { var dualItem = referenceItem.Clone(dualPath.items.LastOrDefault()); try { var refElement = referenceItem.GetValue(nextReference); var dualElement = dualItem.GetValue(nextDual); } catch (Exception) { dualPaths.RemoveAt(c--); --dualsCount; continue; } dualPath.AddItem(dualItem); } } } return(dualPaths); }
public ShadowContainer(Type type) { isIdentifiable = IdentifiableHelper.IsIdentifiable(type); }