Click here to Skip to main content
15,886,199 members
Articles / Programming Languages / XML

Creating custom configuration for application layers

Rate me:
Please Sign up or sign in to vote.
4.00/5 (2 votes)
19 Jan 2010CPOL4 min read 17.8K   10   7
This article describes the cool feature of creating custom configuration for application layer integration.

Introduction

There are several features of the .NET framework that we generally overlook or are left unimplemented in our business solutions, but these small, although very useful, features can make our life really cool. From the stack of those features, today, I want to discuss the powerful feature of custom configuration, which enables us to integrate our application layers from a single configuration file, in a clear, declarative way.

Background

Some days ago, I was working on a business solution using ASP.NET 2.0, C#, SQL Server 2005, etc. It was a Workflow based large Enterprise application. There were several generic (please don't get confused with the .NET Framework Generic feature) layers which were responsible for serving different types of services. These layers were supposed to share some common configuration related information (e.g.: database connection strings, LDAP connection string, and much more) which were declared in the web.config file (in the ConnectionStrings block).

Now, the problem was how to share these connection strings (or various settings) around the layers, so that we don't need to hardcode the key names.

The solution was very simple, and was inbuilt in the .NET Framework. We just took the help of System.Configuration, and we were up with a declarative syntax to share the configuration from the web.config file.

Implementing a custom configuration

It is always a better option for me, and I believe for all, to go through a concrete implementation for grasping the concept. So, I would like to give an example of a class library project which in turn needs to be integrated in a web application, and needs to share some configurations (like database connection string and Active Directory connection string)

For declaring the connection strings, .NET Framework 2.0 has a very unique section in the configuration file: the <connectionStrings> section. Suppose we have two entries in the <connectionStrings> section, something like in the following snippet:

XML
<connectionStrings>
   <add name="DBConnection" 
     connectionString="string to connect database" 
     providerName="System.Data.SqlClient"/>
   <add name="ADConnection" 
     connectionString="string to connect Active Directory"/>
</connectionStrings>

Now, let's go to the class library project which needs these two connections (the ASP.NET application also needs these connections for its internal business logic implementation).

There are two ways to achieve sharing of these connection strings:

  1. Hard coding the key names (DBConnection, Adconnection) in the class library.
  2. Sharing the connection string keys with a declarative syntax for the class library.

The first option is not quite acceptable because in case of any changes in the key names, the class library code needs to modified, or if it is a generic module (something like a utility module) that we can plug-in to various applications, then it will be too hard to accomplish (the same reason that the keys are hardcoded in the code). But in the case of the second option, we need not modify the code of the class library, so it's much easier when it comes to integration and manageability.

Now, to accomplish this task, we just need to add a class which needs to inherit from System.Configuration.ConfigurationSection.

Please go though the following class declaration to get an understanding on this:

C#
using System;
using System.Collections.Generic;
using System.Text;
using System.Configuration;

namespace CustomSettingsProvider
{
    internal class CustomSettings:ConfigurationSection
    {
        [ConfigurationProperty("DBConnection",IsRequired=true)]
        public string DataBaseConnection
        {
            get 
            {
                
                return GetDBConnectionString(this["DBConnection"]);
            }
            set
            {
                this["DBConnection"] = value;
            }
        }

        [ConfigurationProperty("AdConnectionString", IsRequired = true)]
        public string ADConnection
        {
            get {
                return GetADConnectionString(this["AdConnectionString"];
            }
            set {
                this["AdConnectionString"] = value;
            }
        }

        private string GetDBConnectionString(string connectionKey)
        {
            return ConfigurationManager.ConnectionStrings[connectionKey].ConnectionString;
        }
        private string GetADConnectionString(string adConnectionKey)
        {
            return ConfigurationManager.ConnectionStrings[adConnectionKey].ConnectionString;
        }    
    }
}

This class will be used internally by the class library to consume the configuration settings that will be done declaratively in the configuration file.

Now, going to the most interesting elements of the above class:

ConfigurationProperty attribute

This attribute exposes the properties that need to be configured from any configuration file. There are a good number of parameters that we can use, for the default value, the regular expression for validating the values assigned to these properties.

ConfigurationSection class

This class provides the basic plumbing for creating the custom configuration sections and configuration properties. An instance of this class exposes a collection of all the configurable properties.

The private methods

These methods actually extract the connection strings depending upon the key provided in the configuration property attribute.

Now, let's see how any other class in the class library can consume these configuration properties. For this, we will go through another class implementation and also the custom configuration section of the configuration file:

C#
public class CustomSettingsConsumer
{
    private string _dbConnection;
    private string _adConnection;
    public string Connection
    {
        get { return this._dbConnection; }
    }
    public string ADConnection
    {
        get { return this._adConnection; }
    }
    public CustomSettingsConsumer()
    {
        this._dbConnection = ((CustomSettings)
          ConfigurationManager.GetSection("CustomSettings")).DataBaseConnection;
        this._adConnection = ((CustomSettings)
          ConfigurationManager.GetSection("CustomSettings")).ADConnection;
        //some Bll logic 
    }
}

Here is the configuration file:

XML
<configSections>
  <section name="CustomSettings" 
    type="CustomSettingsProvider.CustomSettings"/>
</configSections>
<CustomSettings DBConnection="DBConnection" 
       AdConnectionString="ADConnection" />
   <section name=""CustomSettings"" 
      type=""CustomSettingsProvider.CustomSettings"">
</customsettings>

The <ConfigSections> contains our custom configuration. The value of the name attribute should match the GetSection method's parameter value (refer to the above consumer code). Otherwise, we will not be able to extract the configuration values for the class library. The type attribute represents the class name which is inherited from the System.Configuration.ConfigurationSection class. Now, going to the declarative initialization of the configuration property. The <CustomSettings> element does the initialization here. If you follow the CustomSettings class, you will see that there are two custom configuration properties: DBConnection and ADConnectionString. We are actually initializing the values here (declaratively) just by passing the connection string key names. So, total integration becomes quite easy.

Now, if you follow the constructor of the CustomSettingsConsumer class, you can see how easy it is to get the custom configuration values and to implement any business logic using those resources.

Point of interest

The most important thing that we do after creating the individual layers of a solution is Integration. .NET Framework makes this step quite easy by exposing the System.Configuration assembly. There are many potential classes that we can dig in for making the configuration portion of any application easy and as per our needs.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) Siemens
India India
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralTaking it a step further Pin
John Whitmire26-Jan-10 5:34
professionalJohn Whitmire26-Jan-10 5:34 
GeneralRe: Taking it a step further Pin
senguptaamlan27-Jan-10 0:14
senguptaamlan27-Jan-10 0:14 
GeneralLooks good, but some suggestions Pin
Richard MacCutchan21-Jan-10 3:18
mveRichard MacCutchan21-Jan-10 3:18 
GeneralRe: Looks good, but some suggestions Pin
senguptaamlan21-Jan-10 3:25
senguptaamlan21-Jan-10 3:25 
GeneralRe: Looks good, but some suggestions Pin
Richard MacCutchan21-Jan-10 4:51
mveRichard MacCutchan21-Jan-10 4:51 
GeneralRe: Looks good, but some suggestions Pin
senguptaamlan21-Jan-10 8:29
senguptaamlan21-Jan-10 8:29 
I've downloaded the template, but it seems that I need to have good HTML knowledge.Isn't there any otherway...just like MS Word to easily right the description of the article...format it and upload it or mail it to codeprojet for publishing ?
GeneralRe: Looks good, but some suggestions Pin
Richard MacCutchan21-Jan-10 10:37
mveRichard MacCutchan21-Jan-10 10:37 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.