Механизм работы с настройками плагинов

Дата публикации: 27.10.2010
Дата изменения: не изменялась
Состояние: завершена

    Как правило, настройки плагинов хранятся во внешнем файле, будучи представленными либо в двоичном виде (для компактности и/или скрытия содержимого), либо в текстовом формате (например - в "ini" или "xml" форматах). При работе с настройками очень удобно пользоваться сериализацией и десериализацией, с помощью которых можно автоматически получать полноценные объекты, на основе считанной информации и наоборот - сохранять объекты в двоичном или текстовом виде. Работать с объектной моделью очень удобно (это ни для кого не секрет), поэтому обозначенный мною выше механизм, имеющийся в .Net, весьма полезен. Кроме того - сериализуемые объекты могут передаваться между доменами (AppDomain).

    Если настройки хранятся в xml-файле, то на мой взгляд, удобно считать содержимое файла в объект XElement (условно обозначим этот объект как xmlSettings) с помощью статического метода XElement.Load, после чего из xmlSettings следует получить нужный нам дочерний XElement и выполнить десериализацию этого объекта. После изменения настроек - выполнить обратное действие: десериализуем наш объект в XElement, обновляем им в считанном нами xmlSettings, после чего тот сохраняем в файле настроек. 

    Сериализация возможна только для тех объектов, класс которых помечен атрибутом Serializable, поэтому нужно не забыть добавить его для ваших классов. То, как информация будет представлена внутри вашего xml-объекта, управляется с помощью различных атрибутов, которые вы назначаете свойствам вашего класса. Более подробно насчёт сериализации/десериализации можно почитать в MSDN или других источниках (благо информации на эту тему множество) - не хочу дублировать уже имеющуюся информацию.

    Ниже я написал два метода, один из которых производит сериализацию объекта вашего класса в элемент XElement, а второй метод выполняет обратное действие - десериализацию объекта XElement в экземпляр вашего класса:

   1:  /// <summary>
   2:  /// Сериализовать объект в XElement
   3:  /// </summary>
   4:  /// <typeparam name="T">Тип класса, объект которого подлежит сериализации</typeparam>
   5:  /// <param name="element">Объект, подлежащий сериализации</param>
   6:  /// <returns>Возвращается объект XElement, в который произведена сериализация</returns>
   7:  public static XElement SerializeToXml<T>(T element) where T: new()
   8:  {
   9:      XElement xml = null;
  10:      //Выполняем сериализацию в xml
  11:      XmlSerializer xs = new XmlSerializer(typeof(T));
  12:      using (MemoryStream ms = new MemoryStream())
  13:      {
  14:          xs.Serialize(ms, element);
  15:          ms.Position = 0;
  16:          using (XmlReader tr = XmlReader.Create(ms))
  17:          {
  18:              xml = XElement.Load(tr);
  19:              ms.Close();
  20:              tr.Close();
  21:          }
  22:      }
  23:      return xml;
  24:  }
  25:   
  26:  /// <summary>
  27:  /// Десериализация объекта, упакованного в XElement
  28:  /// </summary>
  29:  /// <typeparam name="T">Тип класса, объект которого должен получиться на выходе</typeparam>
  30:  /// <param name="xml">xml-объект, десериализацию которого нужно выполнить</param>
  31:  /// <returns>Возвращается десериализованный экземпляр указанного класса</returns>
  32:  public static T DeSerializeFromXml<T>(XElement xml) where T : new()
  33:  {
  34:      T obj;
  35:      //Сначала сериализую в поток мой элемент XElement
  36:      XmlSerializer xs = new XmlSerializer(typeof(XElement));
  37:      using (MemoryStream ms = new MemoryStream())
  38:      {
  39:          xs.Serialize(ms, xml);
  40:          ms.Position = 0;
  41:          //Теперь настраиваю сериализатор на извлечение из потока объекта класса T
  42:          xs = new XmlSerializer(typeof(T));
  43:          obj = (T)xs.Deserialize(ms);
  44:          ms.Close();
  45:      }
  46:      return obj;
  47:  }

Эти методы я использую в своей работе.

Comments