Click here to Skip to main content
15,881,730 members
Articles / Programming Languages / C#
Article

Minimalist XML Application Settings

Rate me:
Please Sign up or sign in to vote.
4.83/5 (5 votes)
7 Aug 2011CPOL3 min read 22K   584   13   2
Simple way of storing objects of arbitrary type in an XML settings file
Sample Image

Introduction

This tiny article shows how to store arbitrary objects in XML, particularly for application settings.

Background

I was once interested in implementing custom SettingsProvider that allows storing application settings in separate XML file. SettingsProvider and application settings in .NET are too complex areas to cover in this article, but I took some ideas from there to construct a very simple class that allows storing custom settings. The main requirements were:

  • make it simple - just an XML file and few methods for accessing the settings properties
  • allow to store any type of object (of course, it should be either primitive or serializable type)
  • create the settings property, if not exist; create it with default value

The implementation consists of two classes which will be described in the following sections.

XmlSettings Class

You can use as many XmlSettings instances as you wish (for example, one for common settings and one for the user-specific settings). The XmlSettings object can then load/save settings from/to a XML file.

The settings are loaded from XML in serialized form and are deserialized on-demand. When the settings are saved, the already-serialized data are simply copied back to XML.

Accessing the settings properties is very simple. There are two methods: GetValue<T>(string) and SetValue(string,object). The GetValue needs to provide setting property name and optionally a default value for the property (the default value is returned if property has not been found). When the parameter for default value is not used, the default value of the type - default(T) - is considered (e.g. 0 for int, null for objects).

The last method provided by XmlSettings is Contains to check whether the specified settings property is contained in settings.

XmlSettingsProperty Class

The XmlSettingsProperty is used internally in XmlSettings. It holds the settings property value (either the object itself or serialized as string). This class also provides a means for converting value into string.

The conversion uses two techniques: TypeConverter and binary serialization. In both cases, the settings property value is serialized to string (so it can be stored as XML attribute). The purpose of using TypeConverter is maximum readability of the resulting XML.

Here is an excerpt from the serialization code:

C#
TypeConverter typeConverter = TypeDescriptor.GetConverter(this.value.GetType());

if (typeConverter == null ||
    typeConverter.CanConvertFrom(typeof(String)) == false ||
    typeConverter.CanConvertTo(typeof(String)) == false)
{
    // serialize to binary
    MemoryStream stream = new MemoryStream();

    (new BinaryFormatter()).Serialize(stream, this.value);

    byte[] data = stream.ToArray();

    stream.Close();
    stream.Dispose();

    this.valueSerialized = Convert.ToBase64String(data);
    this.isBinary = true;
}
else
{
    // serialize to String
    this.valueSerialized = typeConverter.ConvertToString(this.value);
    this.isBinary = false;
}

We first try to get a suitable TypeConverter for the settings property value. When the converter provides two-way conversion between the object type and String, it is used. Otherwise, the object is binary serialized to MemoryStream, which is in turn converted to Base64 string.

The de-serialization process works in opposite direction. When de-serializing, we need to know type of the settings property value and how it was serialized. The type is provided when getting the property through XmlSettings.GetValue<T>(string) and the serialization method is specified in settings XML.

Using the Code

The following code sample from the demo application shows the entire workflow:

C#
XmlSettings settings1 = new XmlSettings();

settings1.SetValue("SomeString", "Look, I'm here!");
settings1.SetValue("SomeColor", Color.Maroon);
settings1.SetValue("SomeArray", new[] { 3.5f, 19.02f, 6003.0f });
settings1.SetValue("SomePerson", new Person("John Grant", 35));

Console.WriteLine("Storing settings...");

settings1.Save(FileSettings);

XmlSettings settings2 = new XmlSettings();

Console.WriteLine("Loading settings...");

settings2.Load(FileSettings);

We first create a settings1 object and set some values. Notice that various types of objects can be used as setting property values. There also appears a custom type Person, which is part of the project. This class is decorated by SerializableAttribute to allow being converted.

We save the settings in an XML file and load back in another object called settings2.

The demo application displays all the loaded settings on screen.

History

  • 8/5/2011 - Initial release

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer ImagingShop.com
Czech Republic Czech Republic
Founder of two companies focusing on digital imaging, computer vision and .NET components.

Currently focuses on Image alignment and stitching library for .NET, software consulting and .NET component development.

He loves digital photography, programming, yoga, math, comics drawing, healthy lifestyle and green tea.

Comments and Discussions

 
QuestionSeems a bit like mine Pin
PIEBALDconsult7-Aug-11 8:19
mvePIEBALDconsult7-Aug-11 8:19 
AnswerRe: Seems a bit like mine Pin
Libor Tinka12-Aug-11 6:13
Libor Tinka12-Aug-11 6:13 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.