Beispiel #1
0
        /// <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);
        }
Beispiel #2
0
        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);
        }
Beispiel #3
0
        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);
            }
        }
Beispiel #4
0
            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);
            }