Exemple #1
0
        private fsResult InternalDeserialize_4_Cycles(Type overrideConverterType, fsData data, Type resultType, ref object result)
        {
            if (IsObjectDefinition(data))
            {
                // NOTE: object references are handled at stage 1

                // If this is a definition, then we have a serialization invariant that this is the
                // first time we have encountered the object (TODO: verify in the deserialization logic)

                // Since at this stage in the deserialization process we already have access to the
                // object instance, so we just need to sync the object id to the references database
                // so that when we encounter the instance we lookup this same object. We want to do
                // this before actually deserializing the object because when deserializing the object
                // there may be references to itself.

                int sourceId = int.Parse(data.AsDictionary[Key_ObjectDefinition].AsString);
                _references.AddReferenceWithId(sourceId, result);
            }

            // Nothing special, go through the standard deserialization logic.
            return(InternalDeserialize_5_Converter(overrideConverterType, data, resultType, ref result));
        }
Exemple #2
0
        //...
        fsResult Internal_Deserialize(fsData data, Type storageType, ref object result, Type overrideConverterType)
        {
            //$ref encountered. Do before inheritance.
            if (IsObjectReference(data))
            {
                int refId = int.Parse(data.AsDictionary[KEY_OBJECT_REFERENCE].AsString);
                result = _references.GetReferenceObject(refId);
                return(fsResult.Success);
            }

            var deserializeResult = fsResult.Success;
            var objectType        = result != null?result.GetType() : storageType;

            Type forwardMigrationPreviousType = null;

            // Gather processors and call OnBeforeDeserialize before anything
            var processors = GetProcessors(objectType);

            Invoke_OnBeforeDeserialize(processors, objectType, ref data);

            // If the serialized state contains type information, then we need to make sure to update our
            // objectType and data to the proper values so that when we construct an object instance later
            // and run deserialization we run it on the proper type.
            // $type
            if (IsTypeSpecified(data))
            {
                var typeNameData = data.AsDictionary[KEY_INSTANCE_TYPE];

                do
                {
                    if (!typeNameData.IsString)
                    {
                        deserializeResult.AddMessage(string.Format("{0} value must be a string", KEY_INSTANCE_TYPE));
                        break;
                    }

                    var typeName = typeNameData.AsString;
                    var type     = ReflectionTools.GetType(typeName, storageType);

                    if (type == null)
                    {
                        deserializeResult.AddMessage(string.Format("{0} type can not be resolved", typeName));
                        break;
                    }

                    var migrateAtt = type.RTGetAttribute <fsMigrateToAttribute>(true);
                    if (migrateAtt != null)
                    {
                        // if migrating from another type, save the original type and mutate the current type
                        if (!typeof(IMigratable).IsAssignableFrom(migrateAtt.targetType))
                        {
                            throw new Exception("TargetType of [fsMigrateToAttribute] must implement IMigratable<T> with T being the target type");
                        }
                        forwardMigrationPreviousType = type;
                        if (type.IsGenericType && migrateAtt.targetType.IsGenericTypeDefinition)
                        {
                            type = migrateAtt.targetType.MakeGenericType(type.GetGenericArguments());
                        }
                        else
                        {
                            type = migrateAtt.targetType;
                        }
                    }

                    if (!storageType.IsAssignableFrom(type))
                    {
                        deserializeResult.AddMessage(string.Format("Ignoring type specifier. Field or type {0} can't hold and instance of type {1}", storageType, type));
                        break;
                    }

                    objectType = type;
                } while (false);
            }

            var converter = GetConverter(objectType, overrideConverterType);

            if (converter == null)
            {
                return(fsResult.Warn(string.Format("No Converter available for {0}", objectType)));
            }

            // Construct an object instance if we don't have one already using actual objectType
            if (ReferenceEquals(result, null) || result.GetType() != objectType)
            {
                result = converter.CreateInstance(data, objectType);
            }

            // if migrating from another type, do migration now.
            if (forwardMigrationPreviousType != null)
            {
                //we deserialize versioning first on the old model type and then do migration
                var previousInstance = GetConverter(forwardMigrationPreviousType, null).CreateInstance(data, forwardMigrationPreviousType);
                TryDeserializeVersioning(ref previousInstance, ref data);
                TryDeserializeMigration(ref result, ref data, forwardMigrationPreviousType, previousInstance);
            }
            else
            {
                // if not a forward migration, try deserialize versioning as normal
                TryDeserializeVersioning(ref result, ref data);
            }

            // invoke callback with objectType
            Invoke_OnBeforeDeserializeAfterInstanceCreation(processors, objectType, result, ref data);

            // $id
            if (IsObjectDefinition(data))
            {
                var sourceId = int.Parse(data.AsDictionary[KEY_OBJECT_DEFINITION].AsString);
                _references.AddReferenceWithId(sourceId, result);
            }

            // $content
            if (IsWrappedData(data))
            {
                data = data.AsDictionary[KEY_CONTENT];
            }

            // push collector
            TryPush(result);

            // must pass actual objectType
            deserializeResult += converter.TryDeserialize(data, ref result, objectType);
            if (deserializeResult.Succeeded)
            {
                Invoke_OnAfterDeserialize(processors, objectType, result);
            }

            // pop collector
            TryPop(result);

            return(deserializeResult);
        }
Exemple #3
0
        //...
        fsResult Internal_Deserialize(Type overrideConverterType, fsData data, Type storageType, ref object result, out List <fsObjectProcessor> processors)
        {
            //$ref encountered. Do before inheritance.
            if (IsObjectReference(data))
            {
                int refId = int.Parse(data.AsDictionary[KEY_OBJECT_REFERENCE].AsString);
                result     = _references.GetReferenceObject(refId);
                processors = GetProcessors(result.GetType());
                return(fsResult.Success);
            }

            var deserializeResult = fsResult.Success;

            // We wait until here to actually Invoke_OnBeforeDeserialize because we do not
            // have the correct set of processors to invoke until *after* we have resolved
            // the proper type to use for deserialization.
            processors = GetProcessors(storageType);
            Invoke_OnBeforeDeserialize(processors, storageType, ref data);

            var objectType = storageType;

            // If the serialized state contains type information, then we need to make sure to update our
            // objectType and data to the proper values so that when we construct an object instance later
            // and run deserialization we run it on the proper type.
            // $type
            if (IsTypeSpecified(data))
            {
                var typeNameData = data.AsDictionary[KEY_INSTANCE_TYPE];

                do
                {
                    if (!typeNameData.IsString)
                    {
                        deserializeResult.AddMessage(string.Format("{0} value must be a string", KEY_INSTANCE_TYPE));
                        break;
                    }

                    var typeName = typeNameData.AsString;
                    var type     = ReflectionTools.GetType(typeName, storageType);

                    if (type == null)
                    {
                        deserializeResult.AddMessage(string.Format("{0} type can not be resolved", typeName));
                        break;
                    }

                    if (!storageType.IsAssignableFrom(type))
                    {
                        deserializeResult.AddMessage(string.Format("Ignoring type specifier. Field or type {0} can't hold and instance of type {1}", storageType, type));
                        break;
                    }

                    objectType = type;
                } while (false);
            }

            var converter = GetConverter(objectType, overrideConverterType);

            if (converter == null)
            {
                return(fsResult.Warn(string.Format("No Converter available for {0}", objectType)));
            }

            // Construct an object instance if we don't have one already using actual objectType
            if (ReferenceEquals(result, null) || result.GetType() != objectType)
            {
                result = converter.CreateInstance(data, objectType);
            }

            // invoke callback with storageType
            Invoke_OnBeforeDeserializeAfterInstanceCreation(processors, storageType, result, ref data);

            // $id
            if (IsObjectDefinition(data))
            {
                var sourceId = int.Parse(data.AsDictionary[KEY_OBJECT_DEFINITION].AsString);
                _references.AddReferenceWithId(sourceId, result);
            }

            // $content
            if (IsWrappedData(data))
            {
                data = data.AsDictionary[KEY_CONTENT];
            }

            // must pass actual objectType instead of storageType
            return(deserializeResult += converter.TryDeserialize(data, ref result, objectType));
        }