예제 #1
0
        //Serialization of entities should consider the included fields.
        // -    If A.B is defined as an include on A at the time of materialization, B should also be serialized
        //       and re-attached when A is deserialized.
        private SerializableObjectGraph CreateObjectGraph(object entity)
        {
            var sourceType = entity.GetType();

            //If this is a collection, create a graph for each item in the collection.
            if (TypesUtil.IsNonPrimitiveCollection(sourceType))
            {
                var list = new List <IObjectGraph>();
                foreach (object obj in entity as IEnumerable)
                {
                    list.Add(CreateObjectGraph(obj));
                }
                return(new SerializableCollection
                {
                    Collection = list,
                    InstanceType = sourceType
                });
            }
            else
            {
                var serializableInstance = new SerializableInstance {
                    Object = entity, InstanceType = entity.GetType()
                };
                if (entity is IEntity)
                {
                    var materializationIncludes = GetIncludeExpressions((entity as IEntity)._getIntermediateEntity().IncludeDirectives);
                    foreach (var includeExps in materializationIncludes)
                    {
                        AddIncludes(serializableInstance, includeExps.FieldChain, includeExps.IncludesInCollection);
                    }
                }
                else
                {
                    if (TypesUtil.IsCompilerGeneratedAnonymousType(sourceType))
                    {
                        serializableInstance.Object       = null;
                        serializableInstance.InstanceType = sourceType;
                    }

                    var properties = (entity is IEntity) ? sourceType.GetProperties()
                                     .Where(p => typeof(IEntity).IsAssignableFrom(p.PropertyType) ||
                                            typeof(IEntityCollection).IsAssignableFrom(p.PropertyType)).ToArray()
                            : (TypesUtil.IsPrimitiveDataType(sourceType) || sourceType.IsArray || TypesUtil.IsNonPrimitiveCollection(sourceType)
                                ? new PropertyInfo[] {} : sourceType.GetProperties());

                    foreach (var prop in properties)
                    {
                        var propVal = prop.GetValue(entity, null);

                        //Primitive types can be stored as is.
                        if (TypesUtil.IsPrimitiveDataType(prop.PropertyType))
                        {
                            serializableInstance.IncludedMembers.Add
                            (
                                prop,
                                new SerializableInstance {
                                Object = propVal, InstanceType = prop.PropertyType
                            }
                            );
                            continue;
                        }

                        //This is a single object (possibly an entity); but not a primitive type or a collection
                        if (!TypesUtil.IsNonPrimitiveCollection(prop.PropertyType))
                        {
                            serializableInstance.IncludedMembers.Add
                            (
                                prop,
                                CreateObjectGraph(propVal)
                            );
                        }

                        //Collection of non-primitive types
                        else if (TypesUtil.IsNonPrimitiveCollection(prop.PropertyType))
                        {
                            var itemsInCollection = new List <IObjectGraph>();

                            foreach (var item in (propVal as IEnumerable))
                            {
                                itemsInCollection.Add(CreateObjectGraph(item));
                            }

                            serializableInstance.IncludedMembers.Add
                            (
                                prop,
                                new SerializableCollection
                            {
                                Collection   = itemsInCollection,
                                InstanceType = prop.PropertyType
                            }
                            );
                        }
                    }
                }
                return(serializableInstance);
            }
        }
예제 #2
0
        private void AddIncludes(SerializableObjectGraph objectGraph, MemberExpression includedPropertyChain, IEnumerable <MemberExpression> collectionIncludes)
        {
            var memberExp = ExpressionUtil.GetInnermostMemberExpression(includedPropertyChain);
            var propInfo  = objectGraph.GetInstance().GetType().GetProperty(memberExp.Member.Name);

            if (IsPropertyLoadedOnEntity(objectGraph.GetInstance(), propInfo))
            {
                var propVal = propInfo.GetValue(objectGraph.GetInstance(), null);
                if (propVal == null)
                {
                    return;
                }

                if (TypesUtil.IsNonPrimitiveCollection(propInfo.PropertyType))
                {
                    var collInclude = objectGraph.IncludedMembers.ContainsKey(propInfo) ?
                                      objectGraph.IncludedMembers[propInfo] : null;

                    if (collInclude == null)
                    {
                        var list = new List <IObjectGraph>();

                        foreach (var item in (propVal as IEnumerable))
                        {
                            list.Add(new SerializableInstance {
                                Object = item, InstanceType = item.GetType()
                            });
                        }

                        collInclude = new SerializableCollection
                        {
                            Collection   = list,
                            InstanceType = propInfo.PropertyType
                        };

                        objectGraph.IncludedMembers.Add(propInfo, collInclude);
                    }

                    if (collectionIncludes != null)
                    {
                        foreach (SerializableObjectGraph instanceWrapper in (collInclude as SerializableCollection).Collection)
                        {
                            foreach (var include in collectionIncludes)
                            {
                                AddIncludes(instanceWrapper, include, null);
                            }
                        }
                    }
                }
                else
                {
                    var fieldInclude = objectGraph.IncludedMembers.ContainsKey(propInfo) ?
                                       objectGraph.IncludedMembers[propInfo] : null;

                    if (fieldInclude == null)
                    {
                        fieldInclude = new SerializableInstance {
                            Object = propVal, InstanceType = propInfo.PropertyType
                        };
                        objectGraph.IncludedMembers.Add(propInfo, fieldInclude);
                    }

                    if (includedPropertyChain.GetDepth() > 1)
                    {
                        AddIncludes(fieldInclude,
                                    ExpressionUtil.ReplaceInnermostMemberExpression(includedPropertyChain, Expression.Parameter(memberExp.Type, "x")) as MemberExpression,
                                    collectionIncludes);
                    }
                }
            }
        }