Applications use many forms of configuration data, storing settings that are used in applications, enterprise, client computers, and user settings.

The Configuration Management Application Block (CMAB) is typically used for application settings, but it can be enhanced to support more complicated settings as well.

Virtually all applications require some form of configuration data. Enterprise configuration data includes settings that are global to the organization, including items such as the organization's name, address, and logo. Perhaps more importantly, enterprise configuration may include information such as the address of the enterprise LDAP server or authentication service.

The simplest way to use the CMAB to store enterprise settings is to use a centrally-located XML configuration file.

Client configuration data includes settings that are global to all applications on a client computer. Often, this includes a flag indicating whether the client is a production, test, or development computer. Sometimes the configuration data includes paths to log file locations or other system-level policy settings. Configuration data may also include overrides for enterprise configuration that forces applications to use a test server instead of a production server, for instance.

Application configuration data includes settings that are global to all users for a specific application. Often, application configuration includes settings to configure remote server addresses, local caching, or connection strings. These settings may include overrides for enterprise or client computer configuration settings to provide application-specific requirements.

User configuration data includes settings for specific users of a specific application. This type of data must be stored in a per-user location and preferably supports the concept of roaming user profiles. The primary options for storing user configuration data are isolated storage, the user's Application Data directory, or the registry.

Although the .NET Framework itself provides no direct support for managing client computer or user configuration data, with minor enhancements, the CMAB can be used to manage this data as well.

Enterprise Configuration

The CMAB is often used to read and write configuration data from the application's configuration file. It can also be used to read and write configuration data from other arbitrary XML files as well as the Windows registry or a SQL Server database.

By using the ability to read and write to arbitrary XML files or a SQL Server database, you can use the CMAB to access enterprise configuration data. All that is required is either a central enterprise XML file on a network share or a centrally available SQL Server database that can be used by any application. If either of these conditions can be met, you can use the CMAB for this purpose.

If these conditions can't be met but the data is in some other centrally available location, you could write a custom storage provider to allow access to those settings. An example might be a centrally available LDAP server that contains all enterprise configuration data. You could write an LDAP storage provider that plugs into the CMAB to read from this data store. Writing such a provider is outside the scope of this article.

The simplest way to use the CMAB to store enterprise settings is to use a centrally-located XML configuration file. This is exactly the same as storing any other XML configuration data using the CMAB with the exception that the CMAB is configured to reference the XML in a specific file on a shared network drive.

In the case of Listing 1, the path attribute is used to indicate that the settings are stored in a specific file other than the application configuration file. As long as the H: drive is available enterprise-wide, you can use this technique for enterprise settings.

Client Computer and User Configuration

You can handle client computer and user configuration settings in much the same way as enterprise settings. In this case, you'll want to store the settings somewhere under the system's root directory where Windows itself is installed. The directory tree is ideal, as it is automatically protected against changes by anyone other than administrators yet it can be read by any user.

You can create your own custom storage provider that uses special directories, like the system root.

Another potential location is the Common Files directory under Program Files. This location can be edited by administrators and also the users granted the PowerUser role, which may be useful in some cases.

Any directory on the client will work as long as that directory can be read by all users and preferably can be write-restricted to administrators.

User configuration data should be stored in the user's Application Data directory. This directory is found under the specific user's Documents and Settings directory.

The challenge you face is that none of these directories are in fixed locations. The locations are established when the user installs Windows or adds a new user to the system, and users can override the default. To work around this, the .NET Framework provides the System.Environment.GetFolderPath method. This method can be used to determine the location of special directories, such as System Root, Common Files, and Application Data. Unfortunately the CMAB has no provision for utilizing this information.

What you can do is create your own custom storage provider that uses special directories like the system root. Specifically, you can take the XmlFileStorage provider and create a copy that does token replacement in the file path from the configuration file, replacing %systemroot% with the actual system root directory on the client.

To do this, create a new class in a new class library project named XmlFileStorage, and copy the entire contents of the CMAB's XmlFileStorage.vb file into this new file.

Add an Imports statement to import the Microsoft.ApplicationBlocks.ConfigurationManagement namespace. The code requires access to several CMAB classes, and importing the namespace allows the code to compile.

The class includes a method named Init, which is called by CMAB when the object is initialized with its configuration settings. This is the method that handles the path attribute from the configuration file, and so it is here that you can do your token substitution. The newly added code is highlighted in Listing 2.

With these changes, you can now tell the CMAB to use the specific storage provider, which in turn means that you can use %SystemRoot%, %CommonFiles%, and %ApplicationData% in your file paths.

There's one more enhancement you need to make to the CMAB for user settings. The CMAB assumes that configuration files already exist, and if they don't, it throws an exception. Although this works fine for enterprise, client, and application settings, it isn't useful for user settings. It is impractical to expect each user or administrator to create empty configuration files each time a user is added to a client. To solve this, you can enhance the CMAB to have the option of creating a configuration file if one doesn't already exist.

This enhancement requires that you declare a new instance variable in the XmlFileStorage class.

  Friend Class XmlFileStorage
    Implements IConfigurationStorageWriter
#Region "Declare Variables"
            Private _createFile As Boolean

Then the Init method needs to read a createNew attribute from the application configuration file and store the value.

Inits the provider properties
      _sectionName = sectionName

      Dim createFileString As String = _
        CStr(configStorageParameters("createNew"))
      If Not (createFileString Is Nothing) _
         AndAlso createFileString.Length <> 0 Then
          _createFile = _
            Boolean.Parse(createFileString)
      End If

      _applicationDocumentPath = _
        CType(configStorageParameters("path"), _
        String) '

Finally, if _createFile ends up set to True and if the configuration file doesn't exist, you need to create it by adding code to the Init method, as shown in Listing 3.

Note that this code not only creates an appropriate XML configuration file, but if required, it creates the specified directory. For this to work, the user running the application must have the correct NTFS security to create the directories and file. If the user lacks security permissions, an exception will be thrown.

The CMAB can be used to read and write configuration data from arbitrary XML files, the Windows register, or a SQL Server database.

Having made these changes, you can now tell the CMAB to read and write configuration files from three special directories and to create a configuration file if it doesn't already exist. Listing 4 shows CMAB configuration for client and user configuration files.

For the client configuration, use the %SystemRoot% replacement token. In this case, the CMAB requires that the specified file already exists, but it dynamically locates the file based on the client's specific environment.

For the user configuration, use the %ApplicationDate% token and the createNew attribute to specify that if the file doesn't already exist, the CMAB should create it. Notice that the user configuration file is stored in a folder structure consisting of the company name and the application name. This follows recommended best practices for files under the Application Data directory. Files should be stored under a directory for the company creating the software and then under a directory for the specific application.

Summary

The CMAB provides substantial benefits over the native .NET configuration file scheme for storing application configuration data. With the enhancements described in this article, the CMAB can also be used to handle enterprise, client, and user configuration data.