Software Design

How to use the ConfigurationManager class correctly

I want to talk about a practice that I have found very often in the C# community and it is the use of the static class ConfigurationManager. What I find annoying is how easily this class is spread around our application without thinking in the repercussions that it can bring to us. First of all I don’t consider a good practice that our code should know how we are getting the configuration for our application, tying it to the way that we decide to extract it, and how we know, this could change, let me explain myself better with a snippet of code.

var timeout = ConfigurationManager.AppSettings["timeout"];

In the example above we are telling to our code from where we are getting the timeout configuration, if in certain moment we think that it is a better option instead of defined a value in the appSettings, begin to use the timeout defined in sessionstate  we have to change how we are getting the timeout value completely, it would be:

var timeout = ((SessionStateSection)WebConfigurationManager.GetSection("system.web/sessionState")).Timeout;

If that line of code is spread over the application we have to do the same change through the entire code base getting the risk that we forgot to change it in some places.

A better approach to work with configurations it is create a class which contain all the logic to extract the configuration values, isolating how we do it and from where we are taking it, thus the code would not depends of ConfigurationManager (or whatever configuration provider we are using), it will use our class instead, in that way it is not going to change  in the future. An example of how the class could be is:

public class SystemConfiguration
{
    public long getSessionTimeout()
    {
        return ConfigurationManager.AppSettings["timeout"];
    }
}

We can use our new class in the following way:

SystemConfiguration configuration = new SystemConfiguration();
long timeout = SystemConfiguration.timeout();

Now the code that use the configuration it is disconnected of how we get the values. If we decide to begin to extract our configuration from a XML file we only have to make the changes in only one place and the client code is not going to be affected.

Other important problem of using ConfigurationManager directly in our code is the fact that made the code hard to test since we are not able to mock the ConfigurationManager class, but that problem could be solved using the same strategy that we use above, isolating the use of ConfigurationManager in other class. However we have to do some changes, first of all we have to create an interface

public interface IConfiguration
{
    long getSessionTimeout();
}

and make our class implement the new interface

public class SystemConfiguration : IConfiguration
{
    public long getSessionTimeout()
    {
        return ConfigurationManager.AppSettings["timeout"];
    }
}

Now our code is completely testable.

Concluding

The use of ConfigurationManager may seem very innocent and that innocence make it used indiscriminately in our code base making our code more susceptible to change and less testable, definitively not a good combination.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s