I'm trying to find a simple, clean and fast way to implement an XML config file in C# without any 3rd party tools. It also should replace this restricted System.Configuration.ConfigurationManager
.
using System;
using System.IO;
[Serializable]
public class MyConfigFile
{
// Static Members
public static readonly string ConfigFilename = "myConfig.config";
public static readonly string ConfigFullFilename = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), ConfigFilename);
// Singlton
private static MyConfigFile _myConfig;
public static MyConfigFile Instance
{
get
{
if (_myConfig == null)
{
if (!File.Exists(ConfigFullFilename))
{
_myConfig = new MyConfigFile();
Save();
}
else
{
_myConfig = Load();
}
}
return _myConfig;
}
}
// Constructor
public MyConfigFile()
{
Version = 1;
ValueA = "Important Value";
ValueB = DateTime.Now;
ValueC = false;
}
// Properties
public int Version { get; set; }
public string ValueA { get; set; }
public DateTime ValueB { get; set; }
public bool ValueC { get; set; }
// Static Methodes
public static void Save()
{
System.Xml.Serialization.XmlSerializer xs = new System.Xml.Serialization.XmlSerializer(_myConfig.GetType());
StreamWriter writer = File.CreateText(ConfigFullFilename);
xs.Serialize(writer, _myConfig);
writer.Flush();
writer.Close();
}
public static MyConfigFile Load()
{
System.Xml.Serialization.XmlSerializer xs = new System.Xml.Serialization.XmlSerializer(typeof(MyConfigFile));
StreamReader reader = File.OpenText(ConfigFullFilename);
var c = (MyConfigFile)xs.Deserialize(reader);
reader.Close();
return c;
}
}
This code works fine, but I wonder if you can improve it or have any better ideas.
1 Answer 1
Code
The
StreamReader
/StreamWriter
in the methodsLoad
andSave
should be disposed in a finally block (or better by creating them in ausing
). Otherwise, the object is not disposed if the serialization/deserialization fails.The method
Load
does not check if the file exists. If it doesn't, an exception will be thrown. Probably it is enough to make that method private because it is not a required part of the API.Is there any reason for the My prefix? If not, just
ConfigFile
sounds better to me.Consider to use a more application specific path. For Example SpecialFolders.ApplicationData[CompanyName][Application] for user-specific data or CommonApplicationData[CompanyName][Application] for program-specific data.
API
The path of the config file is defined within the class. That has some disadvantages (central configuration is not possible, the class can not be tested by unit tests, the class is not reusable, ...). Therefore, consider to pass the path as constructor argument instead and do not use the singleton pattern.
Consider to rename the
Instance
property to 'Default' or something like that.The methods
Save
/Load
can not be static if the class lost its singleton status - but that should not be a problem.
-
-
1\$\begingroup\$ @t3chb0t: It's a difference to use my as prefix for instance variables (similar to '_') or as prefix for class names ;) \$\endgroup\$JanDotNet– JanDotNet2016年09月26日 14:49:21 +00:00Commented Sep 26, 2016 at 14:49
Explore related questions
See similar questions with these tags.