Inheritance: IXmlSerializerInternal
Esempio n. 1
0
        public IXmlSerializerInternal GetSerializer <T>(EncryptAttribute encryptAttribute, IXmlSerializerOptions options)
        {
            return(_serializerCache.GetOrAdd(
                       Tuple.Create(typeof(T), encryptAttribute, options),
                       _ =>
            {
                var type = typeof(T);

                if (type == typeof(object) || type == typeof(ExpandoObject))
                {
                    return DynamicSerializer.GetSerializer <T>(encryptAttribute, options);
                }

                IXmlSerializerInternal serializer;

                if (type.IsPrimitiveLike() ||
                    type.IsNullablePrimitiveLike() ||
                    ValueTypes.IsRegistered(type))
                {
                    serializer = new XmlElementSerializer <T>(encryptAttribute, options);
                }
                else if (type.IsAssignableToNonGenericIDictionary() || type.IsAssignableToGenericIDictionary() || type.IsReadOnlyDictionary())
                {
                    serializer = DictionarySerializer.GetSerializer(type, encryptAttribute, options);
                }
                else if (type.IsAssignableToNonGenericIEnumerable() || type.IsAssignableToGenericIEnumerable())
                {
                    serializer = ListSerializer.GetSerializer(type, encryptAttribute, options, null);
                }
                else
                {
                    serializer = CustomSerializer.GetSerializer(type, encryptAttribute, options);
                }

                return serializer;
            }));
        }
        private Func <IXmlSerializerInternal> GetCreateSerializerFunc(PropertyInfo propertyInfo, IXmlSerializerOptions options)
        {
            var redactAttribute = (RedactAttribute)Attribute.GetCustomAttribute(propertyInfo, typeof(RedactAttribute));

            if (redactAttribute == null)
            {
                redactAttribute = options.RedactAttribute;
            }

            var attributeAttribute = (XmlAttributeAttribute)Attribute.GetCustomAttribute(propertyInfo, typeof(XmlAttributeAttribute));

            if (attributeAttribute != null)
            {
                var attributeName = !string.IsNullOrWhiteSpace(attributeAttribute.AttributeName) ? attributeAttribute.AttributeName : propertyInfo.Name;
                NodeType = NodeType.Attribute;
                Name     = attributeName;
                return(() => new XmlAttributeSerializer(propertyInfo.PropertyType, attributeName, redactAttribute, _encryptAttribute, options));
            }

            var textAttribute = (XmlTextAttribute)Attribute.GetCustomAttribute(propertyInfo, typeof(XmlTextAttribute));

            if (textAttribute != null)
            {
                NodeType = NodeType.Text;
                Name     = propertyInfo.Name;
                return(() => new XmlTextSerializer(propertyInfo.PropertyType, redactAttribute, _encryptAttribute, options.ExtraTypes));
            }

            if (redactAttribute != null)
            {
                options = options.WithRedactAttribute(redactAttribute);
            }

            var    elementAttribute = (XmlElementAttribute)Attribute.GetCustomAttribute(propertyInfo, typeof(XmlElementAttribute), false);
            string rootElementName;

            if (IsListProperty(propertyInfo))
            {
                var arrayAttribute     = (XmlArrayAttribute)Attribute.GetCustomAttribute(propertyInfo, typeof(XmlArrayAttribute), false);
                var arrayItemAttribute = (XmlArrayItemAttribute)Attribute.GetCustomAttribute(propertyInfo, typeof(XmlArrayItemAttribute), false);

                if (elementAttribute != null && (arrayAttribute != null || arrayItemAttribute != null))
                {
                    throw new InvalidOperationException("On list types, XmlElementAttribute may not be present with either XmlArrayAttribute or XmlArrayItemAttribute are present.");
                }

                string itemElementName;

                if (elementAttribute != null)
                {
                    rootElementName = null;
                    itemElementName = GetElementName(elementAttribute, x => x.ElementName, propertyInfo.Name);

                    Name = itemElementName;

                    _readsPastLastElement = () => true;
                }
                else
                {
                    rootElementName = GetElementName(arrayAttribute, x => x.ElementName, propertyInfo.Name);

                    var itemElementNameFallback =
                        propertyInfo.PropertyType.IsAssignableToGenericIEnumerable()
                            ? propertyInfo.PropertyType.GetGenericIEnumerableType().GetGenericArguments()[0].GetElementName()
                            : "Item";

                    itemElementName = GetElementName(arrayItemAttribute, x => x.ElementName, itemElementNameFallback);

                    Name = rootElementName;
                }

                NodeType = NodeType.Element;
                return(() => ListSerializer.GetSerializer(propertyInfo.PropertyType, _encryptAttribute, options.WithRootElementName(rootElementName), itemElementName));
            }

            rootElementName = GetElementName(elementAttribute, x => x.ElementName, propertyInfo.Name);

            NodeType = NodeType.Element;
            Name     = rootElementName;
            return(() => XmlSerializerFactory.Instance.GetSerializer(propertyInfo.PropertyType, _encryptAttribute, options.WithRootElementName(rootElementName)));
        }