AppSettingsReader

If you've written .NET apps for any amount of time you know how quickly the <appSettings> section can grow in your config file. I loves me some <appSettings> as much as the next person but what's always bothered me about using it is that you have to read from it using a string name, which has the following downsides:
  • You have to rely on manual find-and-replace whenever you rename a key. Not a lot of promise for reliable refactoring.
  • Config files being the wonderful XML that they are are case-sensitive, so if you type the key name with the wrong case you're out of luck.
  • Key values aren't strongly-typed. All values from <appSettings> are returned as strings, so you have to cast the value appropriately, which leads to all kinds of code that looks like this: Convert.ToInt32(ConfigurationManager.AppSettings["SmtpPort"]), which also means you have to make sure the value for that key will convert and not throw an exception. Ugh.
Recently I finally spent some time thinking how I'd rather do it and came up with the idea of a static class that contains nothing but read-only properties where each property returns the appropriate key value in its correct type. I call this class AppSettingsReader (remember that you should only ever be *reading* from config files) and it looks something like this:

public static class AppSettingsReader
{
    public static string SmtpHost
    {
        get
        {
            return ConfigurationManager.AppSettings["SmtpHost"];
        }
    }

    public static int SmtpPort
    {
        get
        {
            return Convert.ToInt32(ConfigurationManager.AppSettings["SmtpPort"]);
        }
    }
}


And of course this could go on and on according to your needs. So instead of having to write

int port = Convert.ToInt32(ConfigurationManager.AppSettings["SmtpPort"]);

you can now simplify it down to

int port = AppSettingsReader.SmtpPort;

which I find much nicer to work with and has the following advantages:
  • Much easier to refactor.
  • If you rename your <appSettings> keys you only have 1 place to make the changes. The less number of places to look for something the better.
  • Strongly-typed goodness. A value that should be an int is returned as an int.
In actuality this AppSettingsReader class is nothing more than a wrapper on the <appSettings> section in the config file, but I found I really like this approach as it creates tighter code, and I'm all about creating the tightest code possible.
Print | posted on Thursday, September 27, 2007 9:37 PM

Feedback

# re: AppSettingsReader

Gravatar left by Steven Harman at 9/27/2007 11:38 PM
Me Likey!

This approach also allows you to define default values for any fields which you man consider optional for your app's configuration. :)

# re: AppSettingsReader

Gravatar left by moke at 9/28/2007 11:35 AM
If you going that far, why not just implement a ConfigurationSectionHandler and XmlSerialization to solve this problem.

http://www.pluralsight.com/wiki/default.aspx/Craig/XmlSerializerSectionHandler.html

# re: AppSettingsReader

Gravatar left by Dave at 9/28/2007 12:38 PM
Rick - Sure, you can take that approach, but that's really for whole config sections. I'm just talking about all those one-off key-value pairs in <appSettings>.

# re: AppSettingsReader

Gravatar left by dru at 9/28/2007 2:34 PM
This is a great idea. Thank you for sharing. I take it a step further and use a non-static class and then have it implement IConfiguration. This way I don't have to have the .config file in my tests.

-d

# re: AppSettingsReader

Gravatar left by brian prince at 9/30/2007 10:20 PM
uhhh. Yeah. Been doing this for years. I usually call it something different, but the concept is the same. The combination of a static class to manage access to the app setting, and the use of enums to control the keys so you know you haven't broken something at design time is good.

I also use this for session (which I avoid as much as possible).
Comments have been closed on this topic.