public static void Remove(this IDataContainer dc, string key) { if (dc.Find(key) is DataObject obj) { dc.Remove(obj); } }
/// <summary> /// Takes in 2 <see cref="IDataContainer"/> returns a new instance of <see cref="IDataContainer"/> /// Which contains all the properties in LHS and RHS exception the ones that are common to both /// </summary> /// <param name="lhs"></param> /// <param name="rhs"></param> /// <returns></returns> public static IDataContainer Except(this IDataContainer lhs, IDataContainer rhs) { IDataContainer difference = lhs is IPropertyContainer ? (IDataContainer) new PropertyContainer() : new DataContainer(); difference.Name = lhs.Name; foreach (var data in lhs) { difference.Add(data); } var lhsKeys = lhs.GetKeys(); var rhsKeys = rhs.GetKeys(); var intersectKeys = lhsKeys.Intersect(rhsKeys); // no need to handle nested IDataContainer, the root will be removed, no need to worry about children. foreach (var key in intersectKeys) { difference.Remove(lhs.Find(key)); } return(difference); }
/// <summary> /// Takes in 2 <see cref="IDataContainer"/> returns new instance of <see cref="IDataContainer"/> /// which containes properties which are both in LHS and RHS, the values will be from LHS /// </summary> /// <param name="lhs"></param> /// <param name="rhs"></param> /// <returns>LHS ^ RHS</returns> public static IDataContainer Intersect(this IDataContainer lhs, IDataContainer rhs) { IDataContainer intersect = lhs is IPropertyContainer ? (IDataContainer) new PropertyContainer() : new DataContainer(); intersect.Name = lhs.Name; var lhsKeys = lhs.GetKeys(); var rhsKeys = rhs.GetKeys(); var intersectKeys = lhsKeys.Intersect(rhsKeys); foreach (var key in intersectKeys) { DataObject first = lhs.Find(key); // in case of nested IDataContainer if (first.GetValue() is IDataContainer dc) { var second = rhs.Find(first.Name).GetValue() as IDataContainer; if (dc.IsIdentical(second) == false) { first.SetValue(dc.Intersect(second)); } } intersect.Add(first); } return(intersect); }
public void DataObjectFactory_RegisterDataObject_Works() { DataObjectFactory.RegisterDataObject <Utils.PersonDataObject>(); IDataContainer dc = DataContainerBuilder.Create() .Data("person", new Utils.Person { FirstName = "John", LastName = "Doe" }) .Build(); string xml = XmlHelper.SerializeToString(dc); IDataContainer dcNew = XmlHelper.DeserializeFromString <System.Configuration.DataContainer>(xml); Assert.True(dcNew.ContainsData("person")); DataObject dobj = dcNew.Find("person"); Assert.Equal("prsn", dobj.Type); Utils.Person p = dobj.GetValue() as Utils.Person; Assert.Equal("John", p.FirstName); Assert.Equal("Doe", p.LastName); }
/// <summary> /// Removes the properties from first which are common to first and second. /// Same as <see cref="Except(IDataContainer, IDataContainer)"/> but does operation in place instead of returning new instance /// </summary> /// <param name="lhs"></param> /// <param name="rhs"></param> public static void Remove(this IDataContainer lhs, IDataContainer rhs) { foreach (var data in rhs) { if (lhs.Find(data.Name) is DataObject obj) { lhs.Remove(obj); } } }
public void IDataContainer_RaisesCollectionChangedOnRemove() { IDataContainer A = DataContainerBuilder.Create() .Data("A", 1) .Build(); var listener = new CollectionChangedListener(A); Assert.Null(listener.LastChange); DataObject obj = A.Find("A"); A.Remove(obj); Assert.NotNull(listener.LastChange); Assert.Equal(NotifyCollectionChangedAction.Remove, listener.LastChange.Action); Assert.Single(listener.LastChange.OldItems); Assert.Same(obj, listener.LastChange.OldItems[0]); }
/// <summary> /// Add new properties from second to first, if they already exist, keep the values. /// Same as <see cref="Union(IDataContainer, IDataContainer)"/> but does operation inplace instead of returning new intance; /// </summary> /// <param name="lhs"></param> /// <param name="rhs"></param> public static bool Merge(this IDataContainer lhs, IDataContainer rhs) { bool result = false; bool innerResult = false; foreach (var data in rhs) { if (lhs.ContainsData(data.Name) == false) { lhs.Add(data); result = true; } else { DataObject lhsData = lhs.Find(data.Name); // No need to update value, but update the details if (data is PropertyObject propRhs && lhsData is PropertyObject propLhs) { result = propLhs.DisplayName != propRhs.DisplayName || propLhs.Category != propRhs.Category || propLhs.Description != propRhs.Description; propLhs.DisplayName = propRhs.DisplayName; propLhs.Category = propRhs.Category; propLhs.Description = propRhs.Description; } if (lhsData.GetValue() is IDataContainer dc) { IDataContainer rhsDC = data.GetValue() as IDataContainer; bool temp = dc.Merge(rhsDC); innerResult = temp || innerResult; } } } return(result || innerResult); }
/// <summary> /// Reload values from file again /// Doesn't need new properties if added, only updates existing ones /// </summary> /// <param name="dc"></param> public static void Refresh(this IDataContainer dc, IDataContainer changed) { foreach (var data in changed) { object value = data.GetValue(); if (value is IDataContainer changedChild) { DataObject dcChild = dc.Find(data.Name); if (dcChild != null) { IDataContainer dcChildValue = dcChild.GetValue() as IDataContainer; dcChildValue.Refresh(changedChild); } } else { dc.SetValue(data.Name, value); } } }
/// <summary> /// Takes in 2 <see cref="IDataContainer"/> returns a new instance of <see cref="IDataContainer"/> /// which contains all the properties in <paramref name="lhs"/> and <paramref name="rhs"/> /// </summary> /// <param name="lhs"></param> /// <param name="rhs"> LHS V RHS</param> /// <returns></returns> public static IDataContainer Union(this IDataContainer lhs, IDataContainer rhs) { IDataContainer union = lhs is IPropertyContainer ? (IDataContainer) new PropertyContainer() : new DataContainer(); union.Name = lhs.Name; foreach (DataObject obj in lhs) { union.Add(obj); } foreach (DataObject obj in rhs) { if (union.ContainsData(obj.Name) == false) { union.Add(obj); } else { // in case of nested IDataContainer if (obj.GetValue() is IDataContainer dc) { var unionObj = union.Find(obj.Name); IDataContainer unionDC = unionObj.GetValue() as IDataContainer; if (unionDC.IsIdentical(dc) == false) { unionObj.SetValue(unionDC.Union(dc)); } } } } return(union); }
public static void RecursiveRemove(this IDataContainer container, string key) { var split = key.Split('.'); if (split.Length == 1 && container.Find(split.First()) is DataObject obj) { container.Remove(obj); } else { object temp = null; container.GetValue(split.First(), ref temp); if (temp is IDataContainer dc) { dc.RecursiveRemove(string.Join(".", split.Skip(1))); } else { ; } } }
public static DataObject FindRecursive(this IDataContainer container, string key) { var split = key.Split('.'); if (split.Length == 1) { return(container.Find(key)); } else { object temp = null; container.GetValue(split.First(), ref temp); if (temp is IDataContainer dc) { return(dc.FindRecursive(string.Join(".", split.Skip(1)))); } else { return(null); } } }