/// <summary> /// Extract the properties of <paramref name="data"/> and set baseline values with the result. Id must be specified in the parameter or must be /// specified by the object via the <see cref="StratabaseIdAttribute"/> or the operation will fail. /// </summary> public bool SetBaselineFromPropertiesOf(Guid?id, object data) { var objectEvaluation = ObjectEvaluation.Generate(id, null, data); if (objectEvaluation == null) { return(false); } this.SetBaselineData(objectEvaluation); return(true); }
public void SetObjectWithProperties <T> (T source) { if (source == null) { return; } if (!ObjectEvaluation.DetermineObjectId(source, out Guid id)) { throw new ArgumentException($"Object of type {source.GetType().Name} passed in to {nameof(SetObjectWithProperties)} was not assigned a StratabaseId in it's class layout, nor passed in with a guid."); } this.SetObjectWithProperties(id, source); }
private void SetBaselineData(ObjectEvaluation objectEvaluation) { ObjectDataAccessManager accessManager = EnsureDataAccess(objectEvaluation.Id); foreach (KeyValuePair <string, object> property in objectEvaluation.ValueStorage) { accessManager.SetBaselineValue(property.Key, property.Value); } //#error using it foreach (ObjectEvaluation ancillary in objectEvaluation.AncillaryElements) { this.SetBaselineData(ancillary); } foreach (KeyValuePair <string, ObjectEvaluation> childObject in objectEvaluation.ChildObjectStorage) { accessManager.SetBaselineValue(childObject.Key, childObject.Value.Id); this.SetBaselineData(childObject.Value); } foreach (KeyValuePair <string, ObjectEvaluation.ListInfo> listProp in objectEvaluation.InsertGenerationLists) { if ((listProp.Value.Elements?.Length ?? 0) == 0) { continue; } Type elementType = listProp.Value.ElementType ?? listProp.Value.Elements[0].GetType(); Type listAccessType = typeof(StrataPropertyListAccess <>).MakeGenericType(elementType); // In order to keep some kind of strong access of the method (for refactoring & compiling errors), using object // as a sort of unknown sinceit's just to get nameof. string methodName = nameof(StrataPropertyListAccess <object> .GenerateStorageForBaselineListAccess); object storage = ReflectionXT.RunStaticMethod(listAccessType, methodName, (object)(listProp.Value.Elements)); this.SetBaselinePropertyValue(objectEvaluation.Id, listProp.Key, storage); } }
public static ObjectEvaluation Generate(Guid?foundId, string idPropertyName, object source, string parentPropertyChain = null) { if (source == null) { return(null); } Type sourceType = source.GetType(); if (sourceType.IsSimpleType()) { return(null); } var allProperties = DeterminePropertiesFor(sourceType); Dictionary <string, object> simpleProperties = new Dictionary <string, object>(); Dictionary <string, ObjectEvaluation> subObjects = new Dictionary <string, ObjectEvaluation>(); Dictionary <string, ListInfo> insertGenerationLists = new Dictionary <string, ListInfo>(); List <ObjectEvaluation> ancillaryElements = new List <ObjectEvaluation>(); string propertyNamePrefix = parentPropertyChain == null ? String.Empty : $"{parentPropertyChain}."; var classIdAttr = sourceType.GetAttributes <StratabaseIdAttribute>().FirstOrDefault(); foreach (PropertyInfo prop in allProperties) { if (!foundId.HasValue && classIdAttr != null && (prop.Name == classIdAttr.PropertyName || prop.Name == idPropertyName)) { ThrowIfTypeIsNotGuid(sourceType, prop); foundId = (Guid)prop.GetValue(source); continue; } var propIdAttr = prop.GetAttributes <StratabaseIdAttribute>().FirstOrDefault(); if (!foundId.HasValue && propIdAttr != null && propIdAttr.IsClassDefault) { ThrowIfTypeIsNotGuid(sourceType, prop); foundId = (Guid)prop.GetValue(source); continue; } Lazy <object> lazyInstanceGenerator = new Lazy <object>(() => prop.GetValue(source)); string subObjectName = propertyNamePrefix + prop.Name; // Got a sub object over here... if (!prop.PropertyType.IsSimpleType()) { if (prop.PropertyType.IsArray || (typeof(IList).IsAssignableFrom(prop.PropertyType) && prop.PropertyType.GenericTypeArguments.Length == 1)) { IList elementValues = lazyInstanceGenerator.Value as IList; if (elementValues == null) { continue; } StrataListConfigAttribute listConfigAttr = prop.GetAttributes <StrataListConfigAttribute>().FirstOrDefault() ?? StrataListConfigAttribute.Default; // ========= Reference lists ======================= if (listConfigAttr.BuildReferenceList) { if (listConfigAttr.Config == eStrataListConfig.StoreListDirectly) { throw new ArgumentException($"List {prop.Name} was marked up with [StrataListConfig] to indicate reference list generation and direct list storage, which is incompatible."); } List <object> elementIds = new List <object>(); int index = 0; foreach (object element in elementValues) { var elementEval = ObjectEvaluation.Generate(null, null, element); if (listConfigAttr.Config == eStrataListConfig.GenerateInsertOverrides) { if (elementEval == null) { throw new ArgumentException($"Error - StratabaseId on class {element.GetType().Name} from list {subObjectName} could not determine id. Please markup list with [StrataListConfig] attribute or element class with [StratabaseId] attribute."); } ancillaryElements.Add(elementEval); elementIds.Add(elementEval.Id); } else if (listConfigAttr.Config == eStrataListConfig.GenerateIndexedSubProperties) { string name = $"{subObjectName}[{index++}]"; if (elementEval != null) { subObjects.Add(name, elementEval); } else { simpleProperties.Add(name, element); } } } if (elementIds.Count > 0 && listConfigAttr.Config == eStrataListConfig.GenerateInsertOverrides) { insertGenerationLists.Add(subObjectName, new ListInfo(elementIds.ToArray(), typeof(Guid))); } } // ========= Whatever is in 'em lists ============== else { if (listConfigAttr.Config == eStrataListConfig.GenerateInsertOverrides) { insertGenerationLists.Add(subObjectName, new ListInfo(elementValues.OfType <object>().ToArray(), listConfigAttr.ElementType)); } else if (listConfigAttr.Config == eStrataListConfig.StoreListDirectly) { // Otherwise store as just list simpleProperties.Add(subObjectName, elementValues); } else if (listConfigAttr.Config == eStrataListConfig.GenerateIndexedSubProperties) { string idPropName = null; if (propIdAttr != null && !propIdAttr.IsClassDefault) { idPropName = propIdAttr.PropertyName; } int index = 0; foreach (object item in elementValues) { string name = $"{subObjectName}[{index++}]"; var result = ObjectEvaluation.Generate(null, idPropName, item, name); if (result != null) { subObjects.Add(name, result); } else { simpleProperties.Add(name, item); } } } } continue; } if (lazyInstanceGenerator.Value == null) { continue; } // Gerenate subobject or subobject info bool isReference = prop.GetAttributes <StratabaseReferenceAttribute>().Any(); ObjectEvaluation subObjectEval = ObjectEvaluation.Generate(null, null, lazyInstanceGenerator.Value, isReference ? null : subObjectName); // Nothing was generated, and if we're here we have a value, so instead put hte value in for simple properties if (subObjectEval == null) { simpleProperties.Add(subObjectName, lazyInstanceGenerator.Value); continue; } // We generated a full on sub object if (isReference && subObjectEval.Id != Guid.Empty) { simpleProperties.Add(subObjectName, subObjectEval.Id); subObjects.Add(subObjectName, subObjectEval); continue; } // We generate subobject property info, add that info to this things info simpleProperties.AddEach(subObjectEval.ValueStorage); subObjects.AddEach(subObjectEval.ChildObjectStorage); } if (lazyInstanceGenerator.Value != null) { simpleProperties.Add(subObjectName, lazyInstanceGenerator.Value); } } if (foundId.HasValue) { return(new ObjectEvaluation(foundId.Value, simpleProperties, subObjects, insertGenerationLists, ancillaryElements)); } else if (parentPropertyChain != null) { return(new ObjectEvaluation(Guid.Empty, simpleProperties, subObjects, insertGenerationLists, ancillaryElements)); } return(null); }