Configure It Out with the Configuration Management Application Block

ost applications require some sort of configuration data, whether it is a file resource, a database connection string, user settings, a Web service URL, or simply organizational branding requirements. To address these issues prior to .NET, developers had to utilize some type of ASCII file such as an ini file, or they could use the Windows registry. Today with .NET, application configuration data can be stored in a specialized XML file called a configuration file.

Every .NET application has two configuration files that it uses for its settings. One is called the machine.config file and the other is called the app.config file for Windows applications or a web.config file for Web applications. The machine.config file stores configuration data at the machine level, applying the configuration data to all applications running on that particular computer. The application configuration file stores configuration data at the application level, and the configuration data applies only to the specific application for which it was created.

For the Data Protection Provider to be used by the CMAB, it must be supported and called by the Configuration Section Provider you are using.

Using the .NET machine or application configuration files is an improvement from having to roll out your own mechanism for reading configuration data, but it has some drawbacks.

  • The machine and application configuration files are read only, which makes storing configuration data in the .NET configuration files at run time impossible.
  • When storing data environment-specific settings such as database connection strings in the configuration file, you have to deploy the file to all computers requiring the application. This can be an issue when an application is promoted from a development environment to production with new configuration data. It is possible to mistype new settings into the .NET configuration file.
  • Security can be a critical issue in some environments. The configuration file is an XML document that can be read by anyone who has access to it. For Web applications, this is more difficult because ASP.NET prevents browsing the web.config file. However, with a Windows application configuration file, if a user has access to the executable, the user also has access to the configuration file.

To address these issues, you can always roll your own solution, but that can be time-consuming, and you probably will have to do a lot of refactoring as your needs grow. The other way to solve these issues is to find some implementation on the Web and tweak it to meet your needs. Microsoft, through its practices and patterns group, has created just such an implementation, called the Configuration Management Application Block or CMAB for short, which addresses the above-mentioned concerns and more.

The Configuration Management Application Block is part of a series of best practice implementations that Microsoft has put together. You can read an article on the Data Access Application Block in the November/December 2004 issue of CoDe Magazine , and an article on the Exception Management Block in the November/December 2002 issue of CoDe Magazine. (These articles are available in the DevX Premier Club.)

The Concept and Design of the CMAB
The CMAB addresses the needs of storing and retrieving application configuration data by creating a simple, consistent, extensible interface, including:

  • A flexible data model, allowing storage of simple name-value pairs or complex hierarchal data such as an XML fragment of user preference data. This flexible representation of configuration data is handled by the Configuration Section Handler or CSH interface.
  • An ability to write to any data store via the Configuration Storage Provider or CSP interface. This gives you the ability to store data as an XML file in a database of your choice, or anything else you can think of.
  • A mechanism to handle security and data integrity. Storing data, such as a connection string in an XML file, can at times be less than ideal. The Data Protection Provider, or DPP interface, provides mechanisms for signing the stored configuration data and encrypting it, helping to ensure that your data is not viewed or edited by unauthorized eyes.
  • An option to cache the data stored by any CSP. With some CSP implementations, it can also refresh the cache when the data changes.

The CMAB provides pre-built implementations of the Configuration Section Handler (CSH), Configuration Storage Provider (CSP), and Data Protection Provider (DPP). You can use these as is, tweak them to meet your specific needs, or create your own implementation from scratch.

Using the CMAB
With the high extensibility of the CMAB, some up-front legwork must be done to insure a successful implementation. This is true for any new component you add to an existing or new application.

Planning

The extensible design of the Configuration Management Application Block allows the creation of new components that plug right in.

The first step is defining what the application is that you are building. During this design phase, you need to determine what application data should be configurable. A good rule of thumb is that any data that can be affected by the application’s environment?such as network infrastructure, geographical location, external resources, and so forth?should be considered configurable data, and be stored in a central location.

The next step is to determine how to store the data. CMAB provides two mechanisms for storing configuration data, listed in Table 1.

Table 1: These Configuration Section Handlers (CSH) are included in CMAB.

CSH Class Implementations

Description

XmlHashtableSectionHandler

Implements a class that takes a Hashtable and serializes it into XmlNode. It also takes serialized XML data and deserializes it back into a Hashtable. This is perfect for name value type data.

XmlSerializerSectionHandler

Implements a class that takes any class that supports the .NET XmlSerializer class and serializes it to an XmlNode. It also handles the deserialization back into its original class.

Once you have determined what data to store and how to store it, you must determine where to store it. Should the configuration data be stored in one central location or multiple locations? Should it be easily modifiable or should the data be encrypted? See Table 2 for the Data Storage Providers in CMAB.

Table 2:These Configuration Storage Providers (CMPs) are included in CMAB.

CSP ClassImplementations

Description

SqlStorage

The SqlStorage provider allows configuration data to be stored in a SQL Server database. The data is stored as an XML document in a text field, making it difficult to update directly. It is suggested that all updates are made through the CMAB.

XmlFileStorage

This implementation allows configuration data to be saved as an XML file that can be stored locally or on a network share.Read-only data can also be stored directly in the .NET configuration file.

RegistryStorage

The RegistryStorage implementation allows data to be stored in the Windows registry. This has the same issues with direct editing as the SqlStorage implementation, and can only apply settings to applications hosted on the local computer.

Getting Set Up
Now that you know what data to store, where to store it, and how it will be stored, you can start implementing the CMAB in your project. First, the CMAB must be compiled before you can add the necessary assembly references that you will need.

Once you have downloaded and installed CMAB, the default location for the code to compile it can be found in the C:Program FilesMicrosoft Application Blocks for .NETConfiguration ManagementCode folder. There is a version for Visual Basic .NET in the VB folder and a C# version in the CS folder. Pick the language of your choice and select the appropriate Microsoft.ApplicationBlocks.ConfigurationManagment solution. You will also find three QuickStart sample solutions in the same folder.

?
Figure 1. Use the Add Reference screen to set up the assembly references to use the CMAB.

Once the solution is selected and opened in Visual Studio .NET, compile the solution and you’re ready to go. The two core CMAB assemblies that need to be referenced in your application are the Microsoft.ApplicationBlocks.ConfigurationManagement.dll, and the Microsoft.ApplicationBlocks.ConfigurationManagement.Interfaces.dll (see Figure 1). These assemblies can be found in the output folder of the specific language solution you used to compile the CMAB. One important thing to note is that if you plan to use the SqlStorage Storage Provider, you must also add Microsoft.ApplicationBlocks.Data.dll as an assembly reference to your application project.

With the necessary assembly references added to your project, it is time to dig into the application configuration file and add some entries to it. In Figure 2, you can see an example of a configuration file. The two main things you will have to do are add two custom configuration declarations XML elements to the element and create a new Custom Configuration Section XML element.

?
Figure 2. This Hashtable configuration example uses a separate XML file to store the configuration data and utilizes the refreshOnChange event.

If your application is a Windows application, make sure an app.config file already exists; for a Web application or Web service, the web.config file is already created for you.

At the top of the config file, look for an element named within the element. If the is not present in your application configuration file, add it in.

Next, add a child XML element to the element. This element needs to be named

. The

element has two attributes?name and type. The name attribute contains the custom section name used to define the different configuration section handlers and which configuration storage provider to use with them. For now, you can make the value of the name attribute applicationConfigurationManagement.

Make the value of the type attribute:

   Microsoft.ApplicationBlocks.ConfigurationManagement.     ConfigurationManagerSectionHandler,     Microsoft.ApplicationBlocks.ConfigurationManagement,     Version=1.0.0.0,Culture=neutral,PublicKeyToken=null 
Author’s Note: There are no spaces or breaks in the preceding code, and it all goes on one line.

Now that the applicationConfigurationManagement section element is created, the second

element to be created within the must be added. The second element allows the CMAB to determine which configuration section handler to use. The second

XML element, like the first, has both a name and a type attribute.

For the purposes of this walk-through, use the CMAB built-in XML Hashtable Serializer Configuration Section Handler so the value attribute is:

   Microsoft.ApplicationBlocks.ConfigurationManagement.      XmlHashtableSectionHandler,Microsoft.      ApplicationBlocks.ConfigurationManagement,      Version=1.0.0.0,Culture=neutral,PublicKeyToken=null

Again, the preceding code is all one line with no spaces or breaks. The name attribute is myConfig. See Table 1 for a listing of the Configuration Section Handlers (CSH) included with CMAB.

Adding a Custom Configuration Section
Now that the custom configuration declarations have been added, the next step is to add the custom configuration section. Again looking at Figure 2, you can see the custom configuration section . Notice that the element name matches the first custom configuration declaration section’s attribute name; this is because the custom configuration declaration section defines a class and assembly used to parse the specified custom configuration section.

Add the XML element to the XML element. Next, add a new XML element called with an attribute called name. The value of the name attribute should correspond with the name attribute in the custom configuration declaration section element that defines which configuration section handler to use.

How many times has the Configuration Settings Fairy changed production settings without your knowledge?

Looking at the application configuration file in Listing 1, the value is myConfig. The element can have up to three child XML elements:

  • The that handles the caching settings
  • The that handles the settings for the Configuration Storage Provider (CSP)
  • The that handles the settings for the Data Protection Provider (DPP)

The element contains two attributes: one called enabled that can be set to true or false, and the other called refresh. For more details on how to set the refresh attribute’s value, look at the section Caching Data later in this article. The example application configuration file in Listing 1 has the cache feature enabled and set to refresh every 15 minutes.

The element, the only required element, defines the data storage provider to use as well as any necessary attributes required by the specific storage provider. Therefore, if the configuration storage provider used a database, you would probably have an attribute to specify a connection string to connect to the database. Table 2 contains a list of the configuration data providers included with the CMAB. Table 3 contains a listing of the configuration storage providers and the corresponding attributes.

The element specifies a data protection provider that can be used for signing and encrypting the stored configuration data. The CMAB comes with two DPPs. They are listed in Table 4. You can find the attributes for these two included DPPs in Table 5.

Table 3: Configuration Storage Provider attributes.

Configuration
Storage Provider (CSP)

Attributes

Description

(Common to all included storage providers)

Assembly

Specifies the assembly name that contains the storage provider. (Required.)

?

Type

Specifies the storage provider class inside the assembly to use. (Required.)

?

Signed

If set to true, the configuration data is signed and the data protection provider must be provided. (Optional.)

?

Encrypted

If set to true, the configuration data is encrypted and the Data Protection Provider (DPP) must be provided. (Optional.)

SqlStorage

connectionStringRegKeyPath

Specifies the Windows registry path where the SQL connection string is stored. (Either this setting or connectionString is required.)

?

connectionString

Specifies the SQL Connection string to use when connecting to a SQL database. (Either this setting or connectionStringRegKeyPath is required.)

?

getConfigSP

Specifies the stored procedure name used for returning configuration data. (Optional. Defaults to cmab_get_config.)

?

setConfigSP

Specifies the stored procedure name used for saving configuration data to the database. (Optional. Defaults to cmab_set_config.)

XmlFileStorage

Path

Specifies the path where the configuration data XML file is stored. (Optional. Defaults to search the application configuration file for a custom configuration element that matches the specified name attribute in the CSH custom configuration declaration.)

?

refreshOnChange

If set to true and when using the CMAB cache feature, any file modification made to the configuration data file refreshes the cached configuration data. (Optional.)

RegistryStorage

registryRoot

Specifies the registry root of where the configuration is stored. (Required.)

?

registrySubKey

Specifies the registry sub key where the configuration data is stored. (Required.)

Table 4: Out of the Box Data Protection Providers (DPPs).

DPP Class Implementations

Description

BCLDataProtection

Utilizes the .NET Cryptography libraries to handle encryption and decryption of configuration data. Utilizing this implementation means you will have to manage encryption keys manually.

DPAPIDataProtection

The DataProtection implementation utilizes the Win32 DPAPI or Data Protection API. This API handles the management of encryption keys for you. The encryption keys can be stored in the user key store, which, on a Windows NT domain with roaming profiles turned on, allows a user to encrypt and decrypt data on any computer on that domain. An alternative is to use the machine key store to allow anyone accessing that particular computer to encrypt and decrypt data.

Table 5: Configuration Storage Provider (CSP) attributes.

Data Protection
Provider

Attributes

Description

(Common to all included data protection providers)

Assembly

Specifies the assembly name that contains the storage provider. (Required.)

?

Type

Specifies the storage provider class inside the assembly to use. (Required.)

?

hashKeyRegistryPath

Specifies the Windows registry path where the hash key is stored. (Either this setting or hashKey is required.)

?

hashKey

Specifies the Hash key to use when encrypting data. (Either this setting or hashKeyRegistryPath is required.)

BCLDataProtection

symmetricKeyRegistryPath

Specifies the Windows registry path where the symmetric key is stored. (Either this setting or symmetricKey is required.)

?

symmetricKey

Specifies the symmetric key to use when encrypting data. (Either this setting or symmetricKeyRegistryPath is required.)

DPAPIDataProtection

keyStore

Specifies the key store to use. (Optional. Defaults to use the machine key to encrypt the data.)

Reading Data
There are two overloaded Read methods. The first method accepts a string parameter that defines the section name you want to use. The section name defines which CSH and CSP will be used for retrieving the configuration data.

In Figure 2, the name attribute in the configSection and section elements are the same, thus passing in myConfig to the Read method will tell the configuration manager to use the XML Hashtable Configuration Section Handler, and the XML File Storage data provider for retrieving the configuration data.

   public object GetAllSettings(   string sectionName)   {      return ConfigurationManager.Read(         sectionName);   }

It is possible to have multiple section handlers and data providers used within the same application just by specifying them in the application configuration file.

The second overloaded Read method accepts no parameters, and it uses the defaultSection attribute of the applicationConfigurationManagement element to define which CSP and CSH to use. One very important thing to note is that the Read method that uses the defaultSection can only be used with Hashtables. If you want to use some other object other than a Hashtable, the Read method must be called with the sectionName parameter.

One very important thing to note is that the Read method that uses the defaultSection can only be used with Hashtables.
   public object GetMySetting(string key)   {      Hashtable configData =          ConfigurationManager.Read();      return configData[key];   }

Writing Data
Writing data to the CSP is just about as easy as reading it. There are two overloaded Write methods. The first overload accepts a section name and an object representing your configuration data and the second overload, using the defaultSection attribute, only accepts the object representing your configuration data. Again, the same Hashtable-only rule applies when using the Write method overload without a parameter as its counterpart Read method.

   public void SaveAllSettings(string sectionName,       object data)   {      ConfigurationManager.Write(sectionName, data);   }

Caching Data
For almost every application, performance can be a concern. The CMAB offers a solution by providing in-memory caching functionality. The caching is really handy when dealing with settings that change rarely.

With some CSPs, such as the included XmlFileStorage provider, an event can be raised within the CMAB to refresh the in-memory cache from the CSP. To use the CMAB caching, a configCache element must be added to the configSection element in your application’s .NET configuration file, and two attributes, enabled and refresh, must be set. The enabled attribute can be set to true or false, allowing caching to be turned on or off. The refresh attribute uses extended format notation.

The extended format consists of five values separated by spaces. These values can consist of an asterisk (*) to represent all possible numbers, a single number to indicate a single value, or a comma-separated list of numbers that can indicate multiple values. The five separate values are as follows, in this exact order: minutes, hours, day of month, month, day of week. Here are some examples of possible different settings

  • 1 * * * *: The cache expires every hour, at 1 minute past the hour.
  • 0,15,30,45 * * * *: The cache expires every 15 minutes for an hour.
  • 0 0,12 * * *: The cache expires at noon and at midnight every day.
  • 0 0 * * 1,2,3,4,5: The cache expires at midnight only on weekdays.
  • 0 12 5 * 0: The cache expires at noon on the first Sunday after the 5th day of every month.

Getting Underneath the Hood
The extensible design of the CMAB allows the creation of new components that plug right in. This extensibility is provided by interfaces. In order to create a new component for the CMAB, inherit from the specific interface for the component being targeted and implement it.

The CSH Interface
The CSH uses the IConfigurationSectionHandler interface in the .NET System.Configuration namespace for reading data and provides a new interface, IConfigurationSectionHandlerWriter, for writing data. The IConfigurationSectionHandler is used to simplify the implementation for storing read-only configuration data in the application or machine configuration files. Providing this ability allows you to use the exact same implementation whether you want to use the standard .NET configuration files or an external data source to store configuration data.

The IConfigurationSectionHandler uses the Create method to deserialize an XML node into an object. It’s up to you to provide the implementation to deserialize the data in much the same way you would when using the IConfigurationSectionHandler.Create method with the .NET configuration files.

The IConfigurationSectionHandlerWriter inherits from IConfigurationSectionHandler and provides a new method that needs to be implemented, called Serialize. This is where you will implement the serialization of your object into an XML node.

Configuration Section Provider Interface
The CSP interfaces provide the means to actually read and write configuration data to and from the data storage provider whether it’s a database, an XML file, or something else. The CSP interfaces consist of the IConfigurationStorageReader interface for read-only operations and the IConfigurationStorageWriter interface for read-and-write operations. It is assumed that if you are going to write data that you are also going to read it as well.

The IConfigurationStorageReader interface has four things to implement; the Init and Read methods, the IsInitialized property and the ConfigChanges event. The Init method is where you initialize your DSP whether it grabs an XML file or sets a connection to a database. The Read method returns an XmlNode from your storage provider. The IsInitialized property indicates whether or not the CSP as been initialized. If you want to support configuration change events, implement the ConfigChanges event.

The IConfigurationStorageWriter inherits from the IConfigurationStorageReader and adds a method called Write, which accepts an XmlNode as a parameter. This method is intended to save the serialized configuration data to the storage provider.

Data Protection Provider Interface
The IDataProtection interface provides the methods necessary to encrypt, decrypt, and sign (hash) data. The four methods that need to be implemented are Init, Encrypt, Decrypt, and ComputeHash.

The Init method initializes the DPP and sets up any necessary variables needed by the specific implementation of the DPP. The Encrypt and Decrypt methods are self-explanatory. The ComputeHash method creates a hash signature of the data provided, which gives you the ability to prevent data from being changed outside of the CMAB. How many times has the configuration settings fairy changed production settings without your knowledge? Now, at least you will know right away.

One important thing to note is that the DPP is intended to work with the CSP. Hence the CSP must support and call the DPP interfaces to utilize your DPP implementation with your configuration data.

The Configuration Management Application Block provides a simple, consistent, and robust interface for handling your application configuration data. It comes with a series of out of the box implementations that can be used right away, tweaked to perfection, or tossed out for a custom implementation that you build. Once the interfaces are implemented and configured, the CMAB’s use could not be any easier or straightforward. Overall, the CMAB should be able to handle most?if not all?your configuration data needs.

Share the Post:
Share on facebook
Share on twitter
Share on linkedin

Overview

The Latest

microsoft careers

Top Careers at Microsoft

Microsoft has gained its position as one of the top companies in the world, and Microsoft careers are flourishing. This multinational company is efficiently developing popular software and computers with other consumer electronics. It is a dream come true for so many people to acquire a high paid, high-prestige job

your company's audio

4 Areas of Your Company Where Your Audio Really Matters

Your company probably relies on audio more than you realize. Whether you’re creating a spoken text message to a colleague or giving a speech, you want your audio to shine. Otherwise, you could cause avoidable friction points and potentially hurt your brand reputation. For example, let’s say you create a

chrome os developer mode

How to Turn on Chrome OS Developer Mode

Google’s Chrome OS is a popular operating system that is widely used on Chromebooks and other devices. While it is designed to be simple and user-friendly, there are times when users may want to access additional features and functionality. One way to do this is by turning on Chrome OS