예제 #1
0
 public static void SerializeCustomSerializerName(XElement root, IXMLCustomSerializer serializer)
 {
     if (root != null)
     {
         root.Add(new XAttribute(Settings.CustomSerializerNameTag, serializer.GetType().FullName.ToXMLValue()));
     }
 }
예제 #2
0
 public XMLCustomSerializerAttribute(Type serializerType)
 {
     if (typeof(IXMLCustomSerializer).IsAssignableFrom(serializerType))
     {
         _serializer = (IXMLCustomSerializer)Activator.CreateInstance(serializerType);
     }
     else
     {
         throw new ArgumentException("Serializer must implement IXMLCustomSerializer interface.");
     }
 }
예제 #3
0
        /// <summary>
        /// Рекурсивно десериализует объект.
        /// </summary>
        public object DeserializeObject(XElement root)
        {
            //Пытаемся получить объект из списка уже сериализованных объектов
            object rootObject = GetCRObject(root);

            if (rootObject != null)
            {
                return(rootObject);
            }

            string typeName = DeserializeTypeName(root);
            Type   rootType = GetTypeByName(typeName, _assemblies);

            //Проверяем наличие custom-сериализатора для данного типа
            XAttribute csAttribute = root.Attribute(Settings.CustomSerializerNameTag);

            //Если он есть
            if (csAttribute != null)
            {
                Type csType = GetTypeByName(csAttribute.Value.FromXMLValue(), _assemblies);
                IXMLCustomSerializer serializer = (IXMLCustomSerializer)CreateInstance(csType);
                rootObject = serializer.Deserialize(root, this);
            }

            else if (rootType == typeof(string))
            {
                rootObject = root.Value.FromXMLValue();
            }

            //Если это Enum, то он сохраняет своё значение как int в атрибут "value__"
            else if (rootType.IsEnum)
            {
                rootObject = _converters[typeof(int)](root.Attribute(Settings.EnumValueAttributeName).Value);
            }

            //Если это массив, то десериализуем его в отдельном методе
            else if (rootType.IsArray)
            {
                rootObject = DeserializeArray(root, rootType);
            }

            else if (rootType.GetInterface(typeof(IDictionary).Name) != null)
            {
                rootObject = DeserializeDictionary(root, rootType);
            }

            if (rootObject != null)
            {
                DeserializeMetadata(root, rootObject);
                return(rootObject);
            }

            //Создаём корневой объект. Для класса создаём новый объект данного типа, для структуры получаем пустой экземпляр.
            rootObject = GetEmptyObject(rootType);

            //Добавляем объект в список кольцевых ссылок
            AddToCRList(root, rootObject);

            DeserializeMetadata(root, rootObject);

            IEnumerable <FieldInfo> fields = rootType.GetFieldsIncludingBase(Settings.DefaultFieldFlags); //получаем список полей, включая автоматически созданные для свойств

            //PropertyInfo[] properties = rootType.GetProperties(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); //получаем списк свойств

            foreach (var field in fields)
            {
                //Проверяем на отсутствие атрибута XMLDoNotSerialize
                if (!field.HasAttribute(typeof(XMLDoNotSerializeAttribute)))
                {
                    CheckCustomConverter(field);

                    //Считываем значение элемента/атрибута с именем данного свойства
                    string   value;
                    XName    xname   = XName.Get(field.GetXMLName());
                    XElement element = root.Element(xname);


                    Type   fieldType;
                    object fieldValue;

                    if (element == null)
                    {
                        fieldType = field.FieldType;
                        XAttribute attribute = root.Attribute(xname);
                        if (attribute == null)
                        {
                            fieldValue = null;
                        }
                        else
                        {
                            value = attribute.Value;
                            Func <string, object> converter;
                            if (_converters.TryGetValue(fieldType, out converter)) //если есть такой конвертер
                            {
                                fieldValue = converter(value.FromXMLValue());      //то это простой тип данных
                            }
                            else
                            {
                                throw new System.Xml.XmlException(String.Format("Converter for {0} not found.", fieldType));
                            }
                        }
                    }
                    else
                    {
                        fieldValue = DeserializeObject(element); //если конвертера нет, то это сложный составной класс - рекурсивно десериализуем его
                    }
                    //Если null, то ничего не присваиваем, чтобы не сбивать значения по умолчанию
                    if (fieldValue != null)
                    {
                        //Устанавливаем значение
                        field.SetValue(rootObject, fieldValue);
                    }
                }
            }

            return(rootObject);
        }