Like most .NET developers, I use an application configuration file to store information that will be needed by my application at run-time. This file commonly includes information such as database connection information, and settings of various types. But what happens if you want to change the values that your application is using while the application is running? Fear not: there is a solution!

Normally, the application configuration file is read once, at start-up. So your settings are cached away by the ConfigurationManager. When you need one of these values, you simply request it from the ConfigurationManager and like magic, you have the value at-hand!

For example, suppose you are working on a multi-threaded application. You want to limit the number of concurrent threads that your application will use to perform some tasks in parallel. This is a fairly common scenario. But at run-time, it seems that you’ve over-estimated the capacity of the server to handle your application (or you’ve over-estimated the efficiency of your code). So instead of the ten concurrent threads that you estimated that the server could handle, you now estimate that the “maxConcurrentThreads” value in your App.config should be closer to four.  “Been there, done that!” may come to mind!

Often, you would resolve this problem by simply stopping your application (or service), updating the App.config file and re-starting your application (or service). This approach may work well, in a lot of (most??) cases.

But what if your application is critical and should not be stopped, once started? Let me offer you a solution.

FileWatcher + Configuration Manager

The FileWatcher class is designed to watch for changes in a directory. File additions, deletions, or updates can be used to trigger events to which a FileWatcher instance can respond. We will use this class, along with our friend the ConfigurationManager to re-load application settings whenever you update the App.config file. The combination of these two classes will give you the ability to change things on-the-fly.

Start by setting up the FileWatcher instance.

// I've declared this at the class level
FileSystemWatcher watcher;

Next, create an instance of your FileWatcher. Depending on your application, it can be something that happens at application start, or in response to some events.

// This code runs in the OnLoad event of my test app. You
// will have to determine the proper place for you to run 
// this code
private void MyForm_Load(object sender, EventArgs e)
{
// Get the path to the active app.Config file
string appConfigPath = 
      AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;

// I'm using a FileInfo object to get the directory path and
// App.Config file name. There's probably a more elegant way...
FileInfo fi = new FileInfo(appConfigPath);
string directoryPath = fi.Directory.FullName;

// create the instance of the FileWatcher
watcher = new FileSystemWatcher(diretoryPath, fi.Name);

// indicates that events will be raised when events happen 
// in our watch folder
watcher.EnableRaisingEvents = true; 

// this registers a method to be called when a file changes 
//in our watch folder
watcher.Changed += watcher_Changed;
}

Lastly, we need to define an event handler which will consume the events raised when the app.Config file is updated. Here, we have a simple method that simply refreshes the “appSettings” section whenever the app.Config file is updated.

//----------------------------------------------------------
// This is the method that handles the event raised when
// the App.config file is changed
//----------------------------------------------------------
void watcher_Changed(object sender, FileSystemEventArgs e)
{
    // In my test app, I'm making changes to a value
    // in the appSettings section, So I'm refreshing
    // the values loaded from that section of the file
    ConfigurationManager.RefreshSection("appSettings");
}

And that’s it.

When you update the app.config file, the FileWatcher detects a change. It then raises an event, which results in the “watcher_Changed” method being called. That event handler refreshes the information loaded from the app.config and the application can now run with the new values. Make sure that you refresh the sections that are likely to be updated. For example, if you expect to make changes to connection strings, be sure to refresh that section.

This is a simple way to make the app.config file be a live object rather than something that is read once-only at application start.

As always, please let me know if you have any questions or comments. If you found this useful, please consider buying me a beer.

Leave a Reply

Your email address will not be published. Required fields are marked *