Settings are represented by a custom type. Since the type is owned by the user it can be fully tailored with little constraint. For example, in WPF it can support INotifyPropertyChanged and be completely bound to your view. It can have in memory default values, be inherited, and even encapsulated logic.
public class MySettings { int Host { get; set;} int Port { get; set;} }
The settings library itself is a static container that manages the saving (serialization) and loading (deserialization) of your in-memory settings object. It also provides a consistent way of accessing the object as well as maintaining its lifetime.
public static class Config<T> where T : new(){ private T _instance = new T(); //Can be made lazy public T Instance { get { return _instance; } } //Instance is created via configurator which //implements the deserialization logic public static void Load(IConfigurator conf, string location){ _instance= conf.Load(location); } //Instance is persisted via configurator which //implements the serialization logic public static void Save(string location){ conf.Save(Instance , location); } }
A simple interface allows you to create your own configurators that define how serialization and deserialization will be performed. The configurators can be fed to the static config class, or the static config class can be written with pre-canned configurators.
interface IConfigurator { T Load<T>(string location); void Save<T>(T settings, string location); }
Using the configuration class is simple. Since the actual settings object is manged by the encapsulating static config class, all you need to do is just call it. Accessing the settings properties without loading will always yield the default memory values. Calling the Load method will update the internal instance of the settings object.
Config<MySettings>.Load(new XmlConfigurator(), "settings.xml");
Once loaded, the Instance property returns a shared instance of in memory settings.
var host = Config<MySettings>.Instance.Host; var port = Config<MySettings>.Instance.Port;
The settings can be easily manipulated in memory.
Config<MySettings>.Instance.Host = host; Config<MySettings>.Instance.Port = port;
The settings can also be saved just as easily.
Config<MySettings>.Save(new DBConfigurator(), sqlConnectionString);