Following VMWare’s desicison to make VMWare server free, Microsoft have followed suit, and made Virtual Server 2005 free too. I’ve been looking at VMWare server as an option to improve the utlisation of our servers, but think it might be worth checking out Microsoft’s offering too (though I’ve used VirtualPC, which is terrible).
Microsoft Virtual Server 2005 for free
Managing configuration settings in .NET
One of my biggest frustrations with .NET, and something which I think Microsoft should have thought of, is the way configurations are managed in applications, especially ASP.NET applications. Although the whole web.config and ConfigurationSettings.AppSettings setup is a step forward from hard-coding settings in Classic ASP, I found moving to this a step back.
Let me explain. Early on, back when I was doing classic ASP development, the team of developers I worked with and myself realised this problem, and implemented a global config.inc.asp file into all projects. In this file, we would have some form of environment detection, typically using the URL, and set things like the ConnectionString, MailServer, and other settings accordingly.
The benefit of doing this is obvious, the entire application can be deployed, and without any changes, will automatically use it’s new environment. It also removes the possibility of overwriting configuration settings, as there is only one configuration file.
When moving to ASP.NET, like everyone else, I began using web.config to store application settings. Typically, during development it would hold the development environment settings, and would be modified when uploaded to live. When new changes are deployed, the web.config is not included in the package, and hence the production environment settings are safe.
However, there are two problems with this. The first is that it depends on a developer explicitly excluding the web.config file from the deployment package. It sounds simple, but when the pressure is on, it’s easy to forget this, and the production environment settings get mistakenly overwritten.
The second problem is with changes to the web.config file. As the application is modified, additional changes may be added into this, and if the file is explicitly excluded from the upload, then the production settings will be incomplete. Hence, it becomes imperative to know whether any specific changes within the web.config file need to be deployed to the production environment.
It is clear this is a process prone to error. There should be an easy way of having only one configuration file, which would include metadata about each environment. The .NET framework should have a ConfigurationSettings class capable of reading this metadata, and loading the configuration settings from the group(s) for the current environment.
Practically every ASP.NET web application I work on nowadays uses a custom built configuration class to manage settings. These are stored in a seperate config file, with metadata about each server. At runtime, the config file is read from disk, and the relevant settings loaded and cached.
Here is the structure:
interface IConfigHandler
{
public static EventHandler ConfigSettingsChanged;
public static string ServerName;
public static Hashtable Settings;
public static string GetSetting(string key, string defaultValue);
public static int GetIntValue(string key, int defaultValue);
}
<appSettings> <global> <add key="GlobalKey" value="GlobalValue" /> </global> <section name="dev"> <servers> <server name="localhost"/> </servers> <settings> <add key="ConnectionString" value="DevConnectionString"/> </settings> </section> <section name="production"> <servers> <server name="production-url"/> </servers> <settings> <add key="ConnectionString" value="ProductionConnectionString"/> </settings> </section> </appSettings>
This custom configuration class has been extremely helpful, and helped to workaround the issues mentioned above. However, as it’s not part of the .NET framework, third-party components and software from other vendors integrated into a custom web application tend to use web.config and are not environment-aware.
Of course, when you have the source code, it’s easy to change – it’s simply a case of changing any calls to ConfigurationSettings.Get to Config.GetSetting, which works seamlessly. However, most of the time, you don’t have the source code, and therefore, are forced to use a combination of web.config and the custom config settings file.
In my ideal world, the .NET framework would have an IConfigurationSettings interface, which would match or closely resemble the definition of the Config class above. Developers would the have the option of creating a class implementing this interface, and specifying this through a setting in web.config. Then, whenever a call to ConfigurationSettings is made, the new class would be used, instead of the standard version, and the new class could have environment detection.
So, Chris Sells asks what ‘pain points’ you experience when configuring, deploying and maintaining distributed .NET applications, and this is my answer. I hope someone at Microsoft takes note and addresses this problem.