Раньше я сталкивался со всевозможными ошибками, создавая класс Xml Singleton, и в итоге отказался от него, так как у меня были повсюду ручки.Я заменил его двумя способами.Одна версия только для чтения, предназначенная для чтения данных, и вторая Использование метода / оператора для записи изменений.
Обычно это шаблон, который я использую:
public class Settings : IDisposable
{
string file = "my settings file";
XElement root;
private Settings()
{
root = XElement.Load(file);
}
private void Dispose()
{
root.Save(file);
}
public static Settings Read { get { return new Settings(); } } // return read-only version
public static void Write(Action<Settings> handler)
{
using(Setting settings = new Settings())
handler(settings);
}
// below here is implentation specific
public XElement Root { get { return root; } }
public string SettingA
{
get { return (string)(Root.Attribute("SettingA") ?? (object)string.Empty); }
set { Set(Root, "SettingsA", value, true); }
}
// I wrote this for another StackOverflow thread
/// <summary>
/// Set any value via its .ToString() method.
/// <para>Returns XElement of source or the new XElement if is an ELEMENT</para>
/// </summary>
/// <param name="isAttribute">true for ATTRIBUTE or false for ELEMENT</param>
/// <returns>source or XElement value</returns>
private XElement Set(XElement source, string name, object value, bool isAttribute)
{
string sValue = value.ToString();
XElement eValue = source.Element(name), result = source;
XAttribute aValue = source.Attribute(name);
if (null != eValue)
eValue.ReplaceWith(result = new XElement(name, sValue));
else if (null != aValue)
aValue.ReplaceWith(new XAttribute(name, sValue));
else if (isAttribute)
source.Add(new XAttribute(name, sValue));
else
source.Add(result = new XElement(name, sValue));
return result;
}
/// <summary>
/// Replace with for XAttribute
/// </summary>
/// <param name="source"></param>
/// <param name="value"></param>
/// <returns></returns>
public static XAttribute ReplaceWith(this XAttribute source, XAttribute value)
{
XElement parent = source.Parent;
if (null == parent)
throw new Exception("Source has no parent");
source.Remove();
parent.Add(value);
return value;
}
}
Я не использовал сериализатор, поэтому не знаю, подойдет ли мой шаблон для вас.Я предпочитаю XElement.
Поэтому, чтобы использовать это, вы, вероятно, написали бы одноэлементный класс, который использует ваш не одноэлементный класс XmlSerialize.Вы получите доступ к нему только через синглтон.
Но вот как я в итоге смогу использовать его следующим образом:
string settingA = Settings.Read.SettingA;
Чтобы сохранить значение, это будет:
Settings.Write(s => s.SettingA = "new value");