Пример #1
0
        internal Base Deserialize(ClassMapping mapping, Base existing = null)
        {
            var mappingToUse = mapping;

            if (mappingToUse == null)
            {
                if (_current.InstanceType is null)
                {
                    throw Error.Format("Underlying data source was not able to provide the actual instance type of the resource.");
                }

                mappingToUse = (ClassMapping)_inspector.Provide(_current.InstanceType);

                if (mappingToUse == null)
                {
                    RaiseFormatError($"Asked to deserialize unknown type '{_current.InstanceType}'", _current.Location);
                }
            }

            if (existing == null)
            {
                var fac = new DefaultModelFactory();
                existing = (Base)fac.Create(mappingToUse.NativeType);
            }
            else
            {
                if (mappingToUse.NativeType != existing.GetType())
                {
                    throw Error.Argument(nameof(existing), "Existing instance is of type {0}, but data indicates resource is a {1}".FormatWith(existing.GetType().Name, mappingToUse.NativeType.Name));
                }
            }

            // The older code for read() assumes the primitive value member is represented as a separate child element named "value",
            // while the newer ITypedElement represents this as a special Value property. We simulate the old behaviour here, by
            // explicitly adding the value property as a child and making it act like a typed node.
            var members = _current.Value != null ?
                          new[] { new ValuePropertyTypedElement(_current) }.Union(_current.Children()) : _current.Children();

            read(mappingToUse, members, existing);
            return(existing);
        }