Click here to Skip to main content
15,894,291 members
Articles / Web Development / ASP.NET

Don’t Use ConfigurationManager!

Rate me:
Please Sign up or sign in to vote.
4.54/5 (9 votes)
15 May 2011CPOL4 min read 74.1K   12   11
If you’re one of those devs that slaps a ConfigurationManager.AppSettings in the middle of a class, then stop, please just stop.

.NET generally has a nice API but some things are problematic when classes are static, like FormsAuthentication or ConfigurationManager, allowing developers to use them anywhere in the code.

If you’re one of those devs that slaps a ConfigurationManager.AppSettings in the middle of a class, then stop, please just stop. I know that it works, but the side effect is that you’re creating a hidden dependency that devs who come along afterwards to maintain the code know nothing about and then get bitten in the ass when they try to change something (yes, I know you should look through the code for things like this, but I was in a hurry, OK?).

To be clear, I believe that settings should be injected into classes that need them rather than having to provide a whole object to handle it (think of a connection string) but if you're refactoring old code and already have the dependency, then it's good to be able to start off by being able to see the dependency rather than have it hidden.

I know what you’re going to say “but it's a static class so I don’t have any other way to use it”, but that’s where you’re wrong, and with a little work, you can have dependency injected, unit tested code loveliness, and in fact, I’ve done the work for you: all you have to do is reuse it!

So what’ve I done? Well, quite simply, just written a wrapper around the ConfigurationManager’s static methods that allow you to use it via an interface and inject it into any class that may need it; let's look at some code to see it a little clearer.

Here, we have an absurdly simple example that demonstrates that just looking at the public interface of this class, you’d have absolutely no idea that it uses ConfigurationManager internally:

C#
1: public class SomeClass
2: {
3:     public void SomeMethod()
4:     {
5:         int value = int.Parse(
                ConfigurationManager.AppSettings["TheValue"]);
6:     }
7: }

At least with the code above, you may go investigating “what lies beneath” and find the hidden dependency, but what if you came across this:

Image 1

My guess is like me, you’d anticipate that the class had been sorted for dependency injection and only needed the two dependencies that its constructor was advertising, and it wasn’t until you got bitten by a problem that you’d look at the code and find:

C#
1: public class SomeClass
2: {
3:     private readonly IDependency1 _firstDependency;
4:     private readonly IDependency2 _secondDependency;
5:  
6:     public public SomeClass(IDependency1 firstDependency, 
              IDependency2 secondDependency)
7:     {
8:         _firstDependency = firstDependency;
9:         _secondDependency = secondDependency;
10:     }
11:  
12:     public void SomeMethod()
13:     {
14:         string theSetting = ConfigurationManager.AppSettings["TheValue"];
15:  
16:         theSetting = theSetting + "ArbitaryValue";
17:  
18:         _secondDependency.TheSetting = theSetting;
19:  
20:     }
21: }

So the solution to both of these problems is to inject the ConfigurationManager into the class and to enable us to do that step forward.

The code is written in .NET 4.0 but should work with .NET 2.0 and above if recompiled to target whatever version of the framework you are working with. For brevities sake, I’m just going to show the second code snippet using IConfigurationManager, which makes the code look like this:

C#
1: public class SomeClass
2:    {
3:        private readonly IConfigurationManager _configurationManager;
4:        ..... 
5:  
6:        public SomeClass(IConfigurationManager configurationManager, 
                           IDependency1 firstDependency, 
7:                         IDependency2 secondDependency)
8:        {....}
9:  
10:        public void SomeMethod()
11:        {
12:            string theSetting = _configurationManager.AppSettings["TheValue"];
13:  
14:            theSetting = theSetting + "ArbitaryValue";
15:  
16:            _secondDependency.TheSetting = theSetting;
17:  
18:        }
19:    }

Now anybody looking at the public interface for this class can see that it has a dependency on IConfigurationManager which in turn should indicate that the code is going to be reading from an App or Web.config. The only difference to the actual code using the configuration setting is the use of the instance variable rather than the static class.

The actual IConfigurationManager project contains the implementations of both ConfigurationManager and WebConfigurationManager (plus tests) to show that you can use IConfigurationManager to replace either of these classes. Currently, only the more common methods and properties have been implemented as following the principle of YAGNI I’ve not bothered adding methods such as OpenExeConfiguration that I don’t need at the moment.

The one extra thing that I have added is the ability to be able to return a strongly typed custom configuration section rather than retrieving a section as an object and then casting it, so instead of:

C#
1: var sect = ConfigurationManager.GetSection("sampleSection")as SampleSectionProvider;

You can do:

C#
1: var sect = _configurationManager.GetSection<SampleSectionProvider>("sampleSection");

I know there’s not a lot of difference but I prefer the generic version since an error will be thrown if it can’t get the appropriate section handler that’s been specified.

One word of warning: the Core project has a dependency on System.Web; this isn’t a problem for me as I’m mostly using this with web projects but if you wanted to use this with a desktop app, you will need to either remove the class from the project or except the assembly dependency.

If you are using ConfigurationManager, then I strongly recommend trying out IConfigurationManager, if not for you, then for the person who has to maintain the code in a few months' time. ;)

This article was originally posted at http://designcoderelease.blogspot.com/feeds/posts/default

License

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


Written By
Nock Consulting
United Kingdom United Kingdom
Passionate developer, designer, Certified Scrum Professional, wanna-be architect, agile evangelist, and presenter.

Comments and Discussions

 
QuestionConfiguration Manager Dependency on library classes Pin
Ted D Wagner11-Feb-22 8:40
Ted D Wagner11-Feb-22 8:40 
QuestionJust remove the ConfigurationManager dependency. Pin
Dismember3-Jun-17 1:07
Dismember3-Jun-17 1:07 
QuestionCould you provide Source Code Pin
Member 849023910-Mar-15 7:40
Member 849023910-Mar-15 7:40 
AnswerRe: Could you provide Source Code Pin
Nathan Gloyn10-Mar-15 8:29
Nathan Gloyn10-Mar-15 8:29 
GeneralMy vote of 5 Pin
devdimi18-May-11 12:18
devdimi18-May-11 12:18 
GeneralMy vote of 5 Pin
Christoph Keller16-May-11 21:35
Christoph Keller16-May-11 21:35 
GeneralYour argument is that the dependency is documented? Pin
Simon_Whitehead15-May-11 14:35
Simon_Whitehead15-May-11 14:35 
GeneralRe: Your argument is that the dependency is documented? Pin
Nathan Gloyn15-May-11 22:25
Nathan Gloyn15-May-11 22:25 
GeneralRe: Your argument is that the dependency is documented? Pin
Simon_Whitehead16-May-11 2:07
Simon_Whitehead16-May-11 2:07 
Point #1) There is nothing stopping them from calling the ConfigurationManager directly though? This first point you make is muted by the second point you make in that "a lot of people don't take the time to read intellisense or documentation which can end up with a lack of understanding on how the code works". If they don't read the documentation and/or intellisense.. whats stopping them from just calling ConfigurationManager directly?

Point #2) In a corporate environment, that would get you fired (most likely) Smile | :) This is obviously different job-to-job, but in my experience; you are given the tools you need to learn the architecture of the application. No business in their right mind would sit you down and say "go for it.. oh, learn the achitecture if you want..". All of the jobs I have come across have also had style guides -> which include lots of "don't"'s Smile | :)

Point #3) This is true.. however, how many App/Web configs have you come across where these sorts of settings aren't stored in a database/xml file anyway? Smile | :) I'm just being picky now.. sorry Smile | :)

Point #4) This is true I guess.. however, as above.. most of your unit testing would be in a proper environment, where these settings aren't stored in the app/web config anyway.

I guess in the end I would say your point is valid.. but not for ConfigurationManager.
If you don't succeed, redefine success!

GeneralRe: Your argument is that the dependency is documented? Pin
Nathan Gloyn16-May-11 10:16
Nathan Gloyn16-May-11 10:16 
GeneralRe: Your argument is that the dependency is documented? Pin
Simon_Whitehead16-May-11 13:28
Simon_Whitehead16-May-11 13:28 

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.