Sideshow Bob
Sideshow Bob

Reputation: 191

How to properly store state in a C# .Net application

I have a list of objects, where each object has a boolean property named "enabled". I want to remember the state of these objects accross application sessions. To do this I have at least 2 options, using the registry or using, the more .net approach, app.config file. I would prefer to do the latter.

However, while static/compiletime key/value assignment is trivial, assigning new keys dynamically to the app.config file seems nontrivial. Do you have an example of how to do this?

My question is, what is the best approach to store properties of a list of objects in .net if you want to avoid the registry?

Upvotes: 2

Views: 4446

Answers (6)

Voicu
Voicu

Reputation: 38

You could use application settings (.settings file) and store your state information there as a key-value structure (dictionary, list of custom objects or whatever). Here you can find more details about using app settings and user settings in C#: http://msdn.microsoft.com/en-us/library/aa730869%28VS.80%29.aspx The app settings will be stored in app.config and the user settings in the user's isolated storage.

Upvotes: 1

Matthew Whited
Matthew Whited

Reputation: 22443

If you don't want to use the app config or the registry you can also check out BinaryFormatter and XmlSerializer. BinaryFormatter will be version dependant while XmlSerializer allows for more human editable files, as well as, easier sharing and upgrading for other projects.

class Program
{
    static void Main(string[] args)
    {
        var obj = new MyObject() { Prop1 = "Hello World!!!" };
        //===
        var bf = new BinaryFormatter();
        using (var fs = File.Open("myobject.bin", FileMode.Create, 
                                  FileAccess.Write, FileShare.None))
            bf.Serialize(fs, obj);
        //===
        MyObject restoredObj = null;
        using (var fs = File.OpenRead("myobject.bin"))
            restoredObj = bf.Deserialize(fs) as MyObject;

        //===
        var xSer = new XmlSerializer(obj.GetType());
        using (var fs = File.Open("myobject.xml", FileMode.Create, 
                                  FileAccess.Write, FileShare.None))
            xSer.Serialize(fs, obj);
        //===
        MyObject restoredObjXml = null;
        using (var fs = File.OpenRead("myobject.xml"))
            restoredObjXml = xSer.Deserialize(fs) as MyObject;

    }
}

[Serializable()]
[XmlRoot("myObject")]
public class MyObject
{
    [XmlAttribute("prop1")]
    public string Prop1 { get; set; }
}

Upvotes: 1

OregonGhost
OregonGhost

Reputation: 23759

What's wrong with application settings? It's the simplest way to store settings (hence the name), since you set it up in the designer and can access it through an auto-generated class, much like the auto-generated resource classes. This data will be stored in the application data directory. There is a default settings file in a WinForms applications, but you can create additional ones easily.

It does not support dynamic key/value pairs either, but you can get around that by using a dictionary (though Dictionary<TKey, TValue> does not serialize to XML, you have to work around that, like using a KeyValuePair list or KeyedCollection for storage).

Upvotes: 2

Locksfree
Locksfree

Reputation: 2702

You can also use the IsolatedStorage

Upvotes: 2

NerdFury
NerdFury

Reputation: 19214

I would serialize the objects to an xml file on exit, and deserialize on startup. This way as your objects change, all properties are maintained.

Upvotes: 0

David Basarab
David Basarab

Reputation: 73351

I would favor saving your state to a database if possible or another file structure. Changing your app.config at run-time is generally not done. I would favor serializing your object to a file, and using that to keep it state.

This will dynamically change the app.config or web.config as the case maybe.

public void ChangeAppSettings(string applicationSettingsName, string newValue)
{
    Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);

    KeyValueConfigurationElement element = config.AppSettings.Settings[applicationSettingsName];

    if (element != null)
    {
        element.Value = newValue;
    }
    else
    {
        config.AppSettings.Settings.Add(applicationSettingsName, newValue);
    }

    config.Save(ConfigurationSaveMode.Modified, true);

    ConfigurationManager.RefreshSection("appSettings");
}

Upvotes: 6

Related Questions