Pros and cons of AppSettings vs applicationSettings (.NET app.config / Web.config)

The basic <appSettings> is easier to deal with - just slap in a <add key="...." value="..." /> entry and you're done.

The downside is: there's no type-checking, e.g. you cannot safely assume your number that you wanted to configure there really is a number - someone could put a string into that setting..... you just access it as ConfigurationManager["(key)"] and then it's up to you to know what you're dealing with.

Also, over time, the <appSettings> can get rather convoluted and messy, if lots of parts of your app start putting stuff in there (remember the old windows.ini file? :-)).

If you can, I would prefer and recommend using your own configuration sections - with .NET 2.0, it's really become quite easy, That way, you can:

  • a) Define your configuration settings in code and have them type-safe and checked
  • b) You can cleanly separate YOUR settings from everyone else's. And you can reuse your config code, too!

There's a series of really good articles on you to demystify the .NET 2.0 configuration system on CodeProject:

  1. Unraveling the mysteries of .NET 2.0 configuration

  2. Decoding the mysteries of .NET 2.0 configuration

  3. Cracking the mysteries of .NET 2.0 configuration

Highly recommended! Jon Rista did a great job explaining the configuration system in .NET 2.0.


Application settings can be controlled from a designer (there is usually a Settings.settings file by default) so its easier to modify and you can access them programmatically through the Settings class where they appear like a strongly typed property. You can also have application and user level settings, as well as default settings for rolling back.

This is available from .NET 2.0 onwards and deprecates the other way of doing it (as far as I can tell).

More detail is given at: msdn.microsoft.com/en-us/library/k4s6c3a0.aspx


I've been using a pattern I found a while back where you use basic xml tags but wrap the settings in a static config class. So - a DIY App.Settings.

DotNetPearls Static Config Pattern

If you do it this way you can:

  • use different sets of config values for different environments (dev, test, prod)
  • provide for sensible defaults for each setting
  • control how values are defined and instantiated

It's tedious to set up but performs well, hides references to key names, and is strongly typed. This kind of pattern works well for config that isn't changed by the application, although you could probably work in support for changes as well.

Config:

<add key="machineName" value="Prod" />
<add key="anotherMachineName" value="Test" />
<add key="EnvTypeDefault" value="Dev" />

<add key="RootURLProd" value="http://domain.com/app/" />
<add key="RootURLTest" value="http://test.domain.com/app/" />
<add key="RootURLDev" value="http://localhost/app/" />

<add key="HumanReadableEnvTypeProd" value="" />
<add key="HumanReadableEnvTypeTest" value="Test Mode" />
<add key="HumanReadableEnvTypeDev" value="Development Mode" />

Config class:

using System;
using System.Collections.Generic;
using System.Web;
using WebConfig = System.Web.Configuration.WebConfigurationManager;

    public static class Config
    {
        #region Properties

        public static string EnvironmentType { get; private set; }

        public static Uri RootURL { get; private set; }

        public static string HumanReadableEnvType { get; private set; }

        #endregion

        #region CTOR

        /// <summary>
        /// Initializes all settings when the app spins up
        /// </summary>
        static Config()
        {
            // Init all settings here to prevent repeated NameValueCollection lookups
            // Can increase performance on high volume apps

            EnvironmentType =
                WebConfig.AppSettings[System.Environment.MachineName] ??
                "Dev";

            RootURL =
                new Uri(WebConfig.AppSettings["RootURL" + EnvironmentType]);

            HumanReadableEnvType =
                WebConfig.AppSettings["HumanReadableEnvType" + Config.EnvironmentType] ??
                string.Empty;
        }

        #endregion
    }