Я разрабатываю управляемую интерфейсом инфраструктуру сериализации для использования с интерфейсами для сериализации данных XML.
Конечная цель состоит в том, чтобы эта структура могла сохранять / загружать состояние объекта (или его части, видимой призмы интерфейса мысли), используя интерфейсы в качестве абстракции.
Размышляя о дизайне, я обнаружил, что используя атрибуты C #, я могу предоставить инфраструктуру с необходимой информацией для
сохранить и загрузить состояние объекта, а также способ, как выполнить сериализацию / десериализацию. В качестве преимущества я обнаружил, что не существует решения, способного к частичному сохранению / восстановлению объекта. Если я опишу данные XML в терминах интерфейса с атрибутами данных, я обнаружу, что больше не требуется иметь зависимость от этого интерфейса из класса (так что классу больше не требуется реализовывать данный интерфейс для XML данные).
У меня есть вопрос об использовании класса XmlObjectSerializer из-за некоторых проблем с юзабилити. Вот пример объявления интерфейса, который тестируется:
Вот учебник для начинающих:
interface IPersonRoot
{
string Name { get; set; }
}
[XmlRootSerializer("Body")]
interface IPersonCustomRoot
{
string Name { get; set; }
}
interface IPersonAttribute
{
[XmlAttributeRuntimeSerializer]
string Name { get; set; }
}
interface IPersonCustomAttribute
{
[XmlAttributeRuntimeSerializer("Id")]
string Name { get; set; }
}
interface IPersonElement
{
[XmlElementRuntimeSerializer]
string Name { get; set; }
}
interface IPersonCustomElement
{
[XmlElementRuntimeSerializer("Head")]
string Name { get; set; }
}
interface IPersonCustomElementString
{
[XmlElementRuntimeSerializer("Head", typeof(string))]
string Name { get; set; }
}
interface IVeryImportantPersonRoot : IPersonRoot
{
Guid Id { get; set; }
}
interface IVeryImportantPersonCustomRoot : IPersonCustomRoot
{
Guid Id { get; set; }
}
[XmlRootSerializer("Spirit")]
interface IVeryImportantPersonCustomRootOverride : IPersonCustomRoot
{
Guid Id { get; set; }
}
interface IVeryImportantPersonAttribute : IPersonAttribute
{
Guid Id { get; set; }
}
interface IVeryImportantPersonCustomAttribute : IPersonCustomAttribute
{
Guid Id { get; set; }
}
interface IVeryImportantPersonElement : IPersonElement
{
Guid Id { get; set; }
}
interface IVeryImportantPersonCustomElement : IPersonCustomElement
{
Guid Id { get; set; }
}
interface IVeryImportantPersonCustomElementOverride : IPersonCustomElement
{
[XmlElementRuntimeSerializer("Guid")]
Guid Id { get; set; }
}
interface IVeryImportantPersonCustomElementOverrideGuid : IPersonCustomElement
{
[XmlElementRuntimeSerializer("Guid", typeof(Guid))]
Guid Id { get; set; }
}
interface IVeryImportantPersonCustomRuntimeSerializer : IPersonCustomElement
{
Guid Id { get; set; }
[XmlColorRuntimeSerializer]
Color Color { get; set; }
}
interface IVeryImportantPersonColor
{
string Name { get; set; }
Guid Id { get; set; }
[XmlColorRuntimeSerializer]
Color Color { get; set; }
}
Вот определение класса XmlObjectSerializer:
public class XmlObjectSerializer
{
//...
public static void Load<T>(string xml, Type type, object value)
{
using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(xml)))
{
XDocument root = XDocument.Load(XmlReader.Create(ms));
string rootName = GetRootName(typeof(T), root.Root.Name.ToString());
IXmlObjectSerializer serializer = Load(root.Root, CreateInternal(null, rootName));
serializer.Deserialize(type, value);
}
}
public static void Load<T>(string xml, object value)
{
using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(xml)))
{
XDocument root = XDocument.Load(XmlReader.Create(ms));
string rootName = GetRootName(typeof(T), root.Root.Name.ToString());
IXmlObjectSerializer serializer = Load(root.Root, CreateInternal(null, rootName));
serializer.Deserialize(typeof(T), value);
}
}
public static string Save<T>(Type type, object value)
{
string rootName = GetRootName(typeof(T), value.GetType().Name);
XmlObjectSerializer result = CreateInternal(null, rootName);
IXmlRuntimeSerializer serializer = result;
serializer.Serialize(type, value);
XDocument root = new XDocument();
return result.ToXmlString();
}
public static string Save<T>(object value)
{
string rootName = GetRootName(typeof(T), value.GetType().Name);
XmlObjectSerializer result = CreateInternal(null, rootName);
IXmlRuntimeSerializer serializer = result;
serializer.Serialize(typeof(T), value);
return result.ToXmlString();
}
public static void Load(Stream data, Type type, object value)
{
XDocument document = XDocument.Load(XmlReader.Create(data));
string rootName = GetRootName(type, document.Root.Name.ToString());
IXmlObjectSerializer serializer = Load(document.Root, CreateInternal(null, rootName));
serializer.Deserialize(type, value);
}
public static void Save(Stream data, Type type, object value)
{
string rootName = GetRootName(type, value.GetType().Name);
XmlObjectSerializer serializer = CreateInternal(null, rootName);
serializer.Save(type, data, value);
}
}
Тогда возникает вопрос:
Лучше ли изменить класс XmlObjectSerializer, чтобы он был более универсальным, например XmlObjectSerializer, или просто скрыть все открытые методы, которые используют тип в качестве аргумента? У меня есть предупреждение статического анализатора компилятора, в котором говорится, что использование универсальных методов (т.е. Load (...), Save (...)) в неуниверсальном классе является плохой практикой и должно быть заменено на метод, принимающий Введите в качестве аргумента.
Проблема в том, должен ли я изменить дизайн класса XmlObjectSerializer, следуя этому правилу (в этом случае я потеряю общий подход), и использовать объект и тип в качестве аргументов или оставить методы нетронутыми.
Можете ли вы дать мне совет, а также примеры кода, связанные с размещенным примером кода?
Phanx