Пример #1
0
        /// <summary>
        /// Adds a new converter that can be used to customize how an object is serialized and
        /// deserialized.
        /// </summary>
        public void AddConverter(fsBaseConverter converter)
        {
            if (converter.Serializer != null)
            {
                throw new InvalidOperationException("Cannot add a single converter instance to " +
                                                    "multiple fsConverters -- please construct a new instance for " + converter);
            }

            // TODO: wrap inside of a ConverterManager so we can control _converters and _cachedConverters lifetime
            if (converter is fsDirectConverter)
            {
                var directConverter = (fsDirectConverter)converter;
                _availableDirectConverters[directConverter.ModelType] = directConverter;
            }
            else if (converter is fsConverter)
            {
                _availableConverters.Insert(0, (fsConverter)converter);
            }
            else
            {
                throw new InvalidOperationException("Unable to add converter " + converter +
                                                    "; the type association strategy is unknown. Please use either " +
                                                    "fsDirectConverter or fsConverter as your base type.");
            }

            converter.Serializer = this;

            // We need to reset our cached converter set, as it could be invalid with the new
            // converter. Ideally, _cachedConverters should be empty (as the user should fully setup
            // the serializer before actually using it), but there is no guarantee.
            _cachedConverters = new Dictionary <Type, fsBaseConverter>();
        }
Пример #2
0
        private fsResult InternalSerialize_1_ProcessCycles(Type storageType, Type overrideConverterType,
                                                           object instance, out fsData data)
        {
            // We have an object definition to serialize.
            try
            {
                // Note that we enter the reference group at the beginning of serialization so that we support
                // references that are at equal serialization levels, not just nested serialization levels, within
                // the given subobject. A prime example is serialization a list of references.
                _references.Enter();

                // This type does not need cycle support.
                fsBaseConverter converter = GetConverter(instance.GetType(), overrideConverterType);
                if (converter.RequestCycleSupport(instance.GetType()) == false)
                {
                    return(InternalSerialize_2_Inheritance(storageType, overrideConverterType, instance, out data));
                }

                // We've already serialized this object instance (or it is pending higher up on the call stack).
                // Just serialize a reference to it to escape the cycle.
                //
                // note: We serialize the int as a string to so that we don't lose any information
                //       in a conversion to/from double.
                if (_references.IsReference(instance))
                {
                    data = fsData.CreateDictionary();
                    _lazyReferenceWriter.WriteReference(_references.GetReferenceId(instance), data.AsDictionary);
                    return(fsResult.Success);
                }

                // Mark inside the object graph that we've serialized the instance. We do this *before*
                // serialization so that if we get back into this function recursively, it'll already
                // be marked and we can handle the cycle properly without going into an infinite loop.
                _references.MarkSerialized(instance);

                // We've created the cycle metadata, so we can now serialize the actual object.
                // InternalSerialize will handle inheritance correctly for us.
                fsResult result =
                    InternalSerialize_2_Inheritance(storageType, overrideConverterType, instance, out data);
                if (result.Failed)
                {
                    return(result);
                }

                _lazyReferenceWriter.WriteDefinition(_references.GetReferenceId(instance), data);

                return(result);
            }
            finally
            {
                if (_references.Exit())
                {
                    _lazyReferenceWriter.Clear();
                }
            }
        }