Simpler configuration sections

Following the documentation of the ConfigurationSection class is a good idea as long as you want a sophisticated full blown and end user friendly configuration section. But sometimes you just want a way to persist some information inside a config file – then simple deserialization may be a better alternative.
I want the following configuration section to switch a feature on or off:

<MyConfig>
  <SuppressAll>false</SuppressAll>
</MyConfig>

To represent this in code i write this simple class:

public class MyConfig
{
    public bool SuppressAll { get; set; }
}

Now I need to implement a reader-class for the config section:

public class ConfigReader : ConfigurationSection
{
    private static MyConfig current;
    private static object sync = new object();

    protected override void DeserializeSection
                         (System.Xml.XmlReader reader)
    {
        var serializer = new XmlSerializer(typeof(MyConfig));
        current = (MyConfig)serializer.Deserialize(reader);
    }

    public static MyConfig Current
    {
        get
        {
            if (current == null)
            {
                ConfigurationManager.GetSection("MyConfig");
            }

            return current ?? new MyConfig();
        }
    }
}

What’s that? Well, it’s a “fake” config section. Inside the config I’ll define the section like this:

<configSections>
  <section name="MyConfig"
            type="Sem.GenericHelpers.Contracts
                  .Configuration.ConfigReader,
                  Sem.GenericHelpers.Contracts"/>
</configSections>

As shown here, I’ll configure the ConfigReader class as the “handler” for the config section. This will cause the configuration manager to instanciate a ConfigReader and call “DeserializeSection” as soon as I call ConfigurationManager.GetSection(“MyConfig”) … which is done in the “Current” property. Instead of reading each node I simply deserialize into my target class and set a static instance of that class, wich is returned inside the “Current” property.
I would call the reader a “fake” config section, because it is initialized like a config section, but the application does not get the config section when calling ConfigurationManager.GetSection(“MyConfig”), nor does this class have properties that do correspond to the config section xml. It’s simply a generic reader for the config section that fools the ConfigurationManager in order to get the abstract DeserializeSection method called with the xml from the config file.

You might also go one step further:

public class ConfigReader<TResult> : ConfigurationSection
    where TResult : class, new()
{
    private static TResult current;
    private static object sync = new object();

    protected override void DeserializeSection(
                           System.Xml.XmlReader reader)
    {
        var serializer = new XmlSerializer(typeof(TResult));
        current = (TResult)serializer.Deserialize(reader);
    }

    public static TResult Current
    {
        get
        {
            if (current == null)
            {
                lock (sync)
                {
                    if (current == null)
                    {
                        ConfigurationManager
                          .GetSection(typeof(TResult).Name);
                    }
                }
            }

            return current ?? new TResult();
        }
    }
}

This config reader is really generic. You would call it like this:

var suppressAll = ConfigReader<MyConfig>.Current.SuppressAll;

The name of the section is determined by the class TResult. You can simply define classes in your code (XML serializable classes) that derive from whatever you want and load the content of that classes from the config.

The drawback of that technique is that you do not have additional configuration features like validation – attaching an attribute “[LongValidator(MinValue = 1, MaxValue = 1000000, ExcludeRange = false)]” will simply do nothing. But the benefit is: MUCH less code 😉

Advertisements

3 Responses to Simpler configuration sections

  1. Very useful post. Using the generics in the config reader is pretty cool. I had made some progress in reducing dependencies on app config files by implementing some code that could return IConfigurationSection or just the raw Xml from a section and the consumer would have to deserialize but the generics will solve this issue. Great stuff. Thanks.

  2. […] can use some custom ConfigurationManager or extend the .NET configuration engine. But what about defining defaults for your configuration? Defaults for different scenarios maybe? […]

  3. Nice to see that it’s useful for other people, too – I always try to reduce code to ist minimum, because every line of code is a potential bug 😉

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Sylvio's Infobox

Aktuelle Themen rund um SQL Server, BI, Windows, ...

Meredith Lewis

Professional Digital Portfolio

Vittorio Bertocci

Just another WordPress.com weblog

ScottGu's Blog

Just another WordPress.com weblog

AJ's blog

Thoughts and informations I think worthwhile to share...

Outlawtrail - .NET Development

Architecture & Design

SDX eXperts Flurfunk

Just another WordPress.com weblog

%d bloggers like this: