public static void SerializeCustomSerializerName(XElement root, IXMLCustomSerializer serializer) { if (root != null) { root.Add(new XAttribute(Settings.CustomSerializerNameTag, serializer.GetType().FullName.ToXMLValue())); } }
public XMLCustomSerializerAttribute(Type serializerType) { if (typeof(IXMLCustomSerializer).IsAssignableFrom(serializerType)) { _serializer = (IXMLCustomSerializer)Activator.CreateInstance(serializerType); } else { throw new ArgumentException("Serializer must implement IXMLCustomSerializer interface."); } }
/// <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); }