Dave Donaldson

Critical thinking in software development

Search

Advertisement

Subscribe

Technorati

View blog authority
View blog reactions

My Tweets

  • @hkarthik GoW2 will support up to 10 in multiplayer. An improvement from 8, but I wish they would've doubled it.
  • @hkarthik Weekly GoW2 matches work for me, but I already know I'll be on every night anyway.
  • Played a couple hours of Gears of War co-op tonight with @fallenrogue. Trying to get back in form for Nov 7.

AppSettingsReader

Friday, September 28 2007

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.

Similar Posts

  1. NHibernateRepository
  2. ArgumentHelper and Consistent Exception Messages
  3. Sample Usage of NHibernateRepository

5 comment(s) so far

Me Likey!

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

moke wrote on January 23, 2008

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

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>.

dru wrote on January 23, 2008

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

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).

Post your comment

Comment