//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); } }
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); } } } }