private IEnumerable <string> GetAllUsedNamespaces <T>(T value)
        {
            var result = new List <string>();

            void onScanChild(ContentTypeSerializer contentTypeSerializer, object child)
            {
                if (child == null)
                {
                    return;
                }

                var childType = child.GetType();

                if (contentTypeSerializer.TargetType == childType)
                {
                    return;
                }

                if (contentTypeSerializer.TargetType.IsGenericType &&
                    contentTypeSerializer.TargetType.GetGenericTypeDefinition() == typeof(Nullable <>) &&
                    contentTypeSerializer.TargetType.GetGenericArguments()[0] == childType)
                {
                    return;
                }

                if (_serializer.HasTypeAlias(childType))
                {
                    return;
                }

                var childNamespace = childType.Namespace;

                if (string.IsNullOrEmpty(childNamespace))
                {
                    return;
                }

                result.Add(childNamespace);
            }

            // Force top-level object type to be included.
            onScanChild(_serializer.GetTypeSerializer(typeof(object)), value);

            // Scan child objects.
            var serializer = _serializer.GetTypeSerializer(typeof(T));

            serializer.ScanChildren(_serializer, onScanChild, value);

            return(result);
        }
        protected internal override void ScanChildren(IntermediateSerializer serializer, ChildCallback callback, object value)
        {
            if (serializer.AlreadyScanned(value))
            {
                return;
            }

            // First scan the base type.
            if (_baseSerializer != null)
            {
                _baseSerializer.ScanChildren(serializer, callback, value);
            }

            // Now scan our own elements.
            foreach (var info in _elements)
            {
                var elementValue = info.Getter(value);

                callback(info.Serializer, elementValue);

                var elementSerializer = info.Serializer;
                if (elementValue != null)
                {
                    elementSerializer = serializer.GetTypeSerializer(elementValue.GetType());
                }

                elementSerializer.ScanChildren(serializer, callback, elementValue);
            }

            if (_collectionHelper != null)
            {
                _collectionHelper.ScanChildren(callback, value);
            }
        }
        protected internal override void Initialize(IntermediateSerializer serializer)
        {
            // If we have a base type then we need to deserialize it first.
            if (TargetType.BaseType != null)
            {
                _baseSerializer = serializer.GetTypeSerializer(TargetType.BaseType);
            }

            // Cache all our serializable properties.
            var properties = TargetType.GetProperties(_bindingFlags);

            foreach (var prop in properties)
            {
                if (GetElementInfo(serializer, prop, out ElementInfo info))
                {
                    _elements.Add(info);
                }
            }

            // Cache all our serializable fields.
            var fields = TargetType.GetFields(_bindingFlags);

            foreach (var field in fields)
            {
                if (GetElementInfo(serializer, field, out ElementInfo info))
                {
                    _elements.Add(info);
                }
            }

            if (GenericCollectionHelper.IsGenericCollectionType(TargetType, false))
            {
                _collectionHelper = serializer.GetCollectionHelper(TargetType);
            }
        }
示例#4
0
 protected internal override void Initialize(IntermediateSerializer serializer)
 {
     _serializer = serializer.GetTypeSerializer(typeof(T));
     _format     = new ContentSerializerAttribute
     {
         FlattenContent = true
     };
 }
        protected internal override void Initialize(IntermediateSerializer serializer)
        {
            _keySerializer   = serializer.GetTypeSerializer(typeof(TKey));
            _valueSerializer = serializer.GetTypeSerializer(typeof(TValue));

            _keyFormat = new ContentSerializerAttribute
            {
                ElementName = "Key",
                AllowNull   = false
            };

            _valueFormat = new ContentSerializerAttribute()
            {
                ElementName = "Value",
                AllowNull   = typeof(TValue).IsValueType
            };
        }
        public GenericCollectionHelper(IntermediateSerializer serializer, Type type)
        {
            var collectionElementType = GetCollectionElementType(type, false);
            if (collectionElementType == null)
                throw new ArgumentException($"Failed to get collection element type of {type}.");
            _contentSerializer = serializer.GetTypeSerializer(collectionElementType);

            var collectionType = typeof(ICollection<>).MakeGenericType(collectionElementType);
            var countProperty = collectionType.GetProperty("Count");
            if (countProperty == null)
                throw new Exception("Failed to get property for reflection.");
            _countProperty = countProperty;

            var addMethod = collectionType.GetMethod("Add", new[] { collectionElementType });
            if (addMethod == null)
                throw new Exception("Failed to get method for reflection.");
            _addMethod = addMethod;
        }
        private bool GetElementInfo(IntermediateSerializer serializer, MemberInfo member, out ElementInfo info)
        {
            info = new ElementInfo();

            // Are we ignoring this property?
            if (member.GetCustomAttribute <ContentSerializerIgnoreAttribute>() != null)
            {
                return(false);
            }

            var prop  = member as PropertyInfo;
            var field = member as FieldInfo;

            var attrib = member.GetCustomAttribute <ContentSerializerAttribute>();

            if (attrib != null)
            {
                // Store the attribute for later use.
                info.Attribute = attrib.Clone();

                // Default the to member name as the element name.
                if (string.IsNullOrEmpty(attrib.ElementName))
                {
                    info.Attribute.ElementName = member.Name;
                }
            }
            else
            {
                // We don't have a serializer attribute, so we can
                // only access this member thru a public field/property.

                if (prop != null)
                {
                    // If we don't have at least a public getter then this
                    // property can't be serialized or deserialized in any way.
                    if (prop.GetGetMethod() == null)
                    {
                        return(false);
                    }

                    // If there is a setter, but it's private, then don't include this element
                    // (although technically we could, as long as we have a serializer with
                    // CanDeserializeIntoExistingObject=true for this property type)
                    var setter = prop.GetSetMethod(true);
                    if (setter != null && !setter.IsPublic)
                    {
                        return(false);
                    }

                    // If there is no setter, and we don't have a type serializer
                    // that can deserialize into an existing object, then we have no way
                    // for it to be deserialized.
                    if (setter == null && !serializer.GetTypeSerializer(prop.PropertyType).CanDeserializeIntoExistingObject)
                    {
                        return(false);
                    }

                    // Don't serialize or deserialize indexers.
                    if (prop.GetIndexParameters().Any())
                    {
                        return(false);
                    }
                }
                else if (field != null)
                {
                    if (!field.IsPublic)
                    {
                        return(false);
                    }
                }

                info.Attribute = new ContentSerializerAttribute
                {
                    ElementName = member.Name
                };
            }

            if (prop != null)
            {
                info.Serializer = serializer.GetTypeSerializer(prop.PropertyType);
                if (prop.CanWrite)
                {
                    info.Setter = (o, v) => prop.SetValue(o, v, null);
                }
                info.Getter = o => prop.GetValue(o, null);
            }
            else if (field != null)
            {
                info.Serializer = serializer.GetTypeSerializer(field.FieldType);
                info.Setter     = field.SetValue;
                info.Getter     = field.GetValue;
            }

            return(true);
        }
 protected internal override void Initialize(IntermediateSerializer serializer)
 {
     _itemSerializer = serializer.GetTypeSerializer(typeof(T));
 }