Application Configuration

I had cause to recently revisit an old ASP.NET application I’d written way back when I was a development newcomer. Digging around the web.config I found the appSettings section:

<appSettings>
<add key="systemEmailAddress" value="me@me.com" />
<add key="adminEmailAddress" value="me@me.com" />
<add key="templateDirectory" value="~/admin/templates/" />
<add key="installPath" value="~/admin/" />
</appSettings>

You get the idea. There were loads of these, configuring many different aspects of the system. Many should have been configurable by site administrators from some kind of user interface. Technically this is possible – editing the web.config on the fly – but I really wouldn’t recommend it.

Anyway, since then I’ve used this method a number of times, as well as having a Settings database table which stores key/value pairs:

var email = SettingRepository.FindByKey("email");

Or having a Settings table with a single row and columns for each setting to allow it to be mapped to an object:

Settings settings = SettingsRepository.FindFirst();

All three have upsides and downsides but none are particularly satisfying. I’m mulling over which approach to take in my next project which is going to need a fair few of these settings. Which method do you favour? Do you have a fourth way?

Related Articles:

    Post Footer automatically generated by Add Post Footer Plugin for wordpress.

    This entry was posted in configuration. Bookmark the permalink. Follow any comments here with the RSS feed for this post.

    10 Responses to Application Configuration

    1. Erik says:

      For complex configuration I usually implement IConfigurationSectionHandler, as I detail here: http://shadowcoding.blogspot.com/2008/10/configuration-section-handlers-via.html

      One of the benefits of this (that I don’t go into on my blog really) is that you have full control over the processing of your configuration section. One way I exercise this is to add a way to express a separate configuration file for a certain section, then in the code that parses the config section, I load the specified file and parse that instead.

    2. Luke Foust says:

      I find that the AppSettings is all I need 90% of the time. I sometimes use a naming scheme for the keys like:

      “Template.Directory”
      “Template.Enabled”
      “Admin.EmailAddress”

      where I kind of namespace the keys for easier reading.

      When the settings need to be changed on the fly by a UI, I favor the database approach.

    3. Grant Palin says:

      What I’ve done in one project is to create a custom object, with the necessary properties. When changes a re made, the object is serialized to an XML file, with a .config extension. The file can be deserialized when needing to retrieve a value.

      It is not the best system, but it works. Issues include setting up caching, so the file does not need to be read from disk each time a property is retrieved, and because of the IO involved, is not directly testable.

    4. Jason Meckley says:

      It depends on the project. In the past I have used appsettings for everything “changable”, and it’s a pain to maintain. if the app is small then it’s do able, some products I have worked with require keys in the appsettings.

      i like the idea of a key/value settings table in the db. you could put this single table in it’s own schema to keep separate from the core tables. As new keys are needed just make an entry into the table. maybe go 1 step further and save the Type of the value so you can strongly type the SettingsRepository.FindByKey(string);

      1 table 1 row should never be an option. any time a new value is required the db schema changes. this is no different then having a table like
      Product (table)
      Id (key)
      PriceBracket1
      PriceBracket2
      PriceBracket3

      if your using an IoC like Windsor or Structure.Map you could also store configurable otions in a seperate config file and overwrite the file when the settings change. however this seems clunky.

      all in all I really like the idea of the Settings table. I’ll consider that for my next project.

    5. James says:

      I’d say that it depends on several things:

      -Importance of the data-integrity of the settings
      -Who edits the settings and how often
      -Complexity of the setting values
      -What needs access to the settings (do stored procs need access?)
      -Time to develop

      I’d have to disagree with Jason in that one table one row should never be an option. There may be times where enforcing the data-type of certain settings is of utmost importance.

    6. Maxim says:

      And to develop your custom section within your web.config, I highly recommend http://www.codeplex.com/csd

    7. jdn says:

      I actually talk about that here:

      http://blogcoward.com/archive/2008/11/07/Excellent-Code-is-Easily-Deployable-Code.aspx

      Even though it is old school, don’t discount the possibility of using the regiistry or even kick it out with .ini files. Easy to maintain and deploy.

      However it is done, IMO, it is better to have variable configs as part of an environment setup, and not part of the ‘real’ code deploy. It’s probably the one thing I don’t like about .NET .config files, watching people forget (even with ‘automated’ processes) to change the settings when moving from Dev to QA, etc.

    8. Steve Sheldon says:

      At a previous company, the process of changing a web.config involved about three reams of paperwork to create a change management request along with about a two week lead time.

      Changing a database entry through a admin screen was about 2 seconds.

      I’m somewhat intrigued by jdn’s point with regards to configuring aliases in the host file and such, but I don’t feel that it is maintainable. It’s not entirely obvious to a new person looking at the system and trying to understand why it is behaving as it is.

      Since the database typically changes per environment, I don’t see any reason why not create a Settings table and keep your settings there. With the exception of your connectionstring, that is.

      But generally speaking, maintaining configuration items in a .config file is an excercise in frustration unless you are a small team and the developers also happen to admin the servers.

    9. jdn says:

      @Steve

      The hesitation I have with a settings table is that when you work in a place that has dozens of environments (which I have), you then have to have authoritative scripts that maintain the data for each environment. Depending on how SQL code gets deployed, this can be a major hassle. My goal was always to have one deployment package that could be deployed without change into any environment, but if you have to add an entry to a settings table that differs in each environment, you have an extra step, and it (nearly) always gets screwed up.

      Using SQL aliases and host file entries requires authoritative entities, but only (typically) need to be created once, typically durning environment setup, and then you are done.

      Of course, this isn’t suggested as a panacea. And it really does depend on how code deploys are done. On a side note, one maddening thing I’ve seen is when people use SQL aliases, but then create aliases that use the *actual* server names. Which completely defeats the purpose of them (unless there are obscure network issues that allow direct IP address connections but not name lookups, but still…you end up having to create aliases, *and* remember to update .config or Settings table entries at the same time. Crazy).

    10. Reshef Mann says:

      Me too reflected about configuration issues. I decided to write a small library to take care of it. What it does is to map configuration values by convention to an interface declaration (by using Castle’s dictionary adapter behind the scenes).
      By default it takes the values from the .config file however u can specify other configuration sources as well so u can use db table for configuration. The project is here: http://code.google.com/p/configreader/

      I hope u would like it and consider using it in your project.