I wanted to write something about the concept of a “configuration class”, which Emanuele touched on in a discussion about the singleton pattern. Let me start by explaining what I mean by a configuration class. It’s a relatively common “pattern”, although you’ll never find it in any books. I’m going to argue that this is because, like Singleton, it’s the wrong solution to the problem.
.NET has an incredibly flexible XML-based configuration API. However, for the purposes of this discussion, we can concentrate on the bit that most developers use: AppSettings. This is basically just a string hashtable with delusions of grandeur. This is, frankly, the wrong model. What goes wrong?
- Different pieces of code read the same setting for different purposes. e.g. two assemblies both of which use “ConnectionString” as a key.
- Different pieces of code read the same setting in slightly different ways. Maybe one guy made his test for “True” case insensitive, but did everyone?
- The configuration file is a singleton, with all the problems that implies.
- You’ve no idea what bits of code use what configuration settings. Ultimately, this is the one that’s going to kill you.
The Configuration Class
Well, you know that working with the raw hashtable is dangerous bordering on foolhardy. So, you put an abstraction on top of it to fix some of the horror of working the bare metal.* You’ve now got, in effect, a strong typed class with properties that correspond to the settings in your config file. Next, you get the rest of your code to use this class. I’m not going to go into more detail about this since Jeffrey Palermo’s article already does a better job than I would.
Now, this is vastly better than what we started with:
- Different pieces of code using the same setting are now explicit, so your chances of a conflict are much smaller.
- Everyone now reads the setting the same way.
- You’ve separated yourself from the physical configuration file, so you can use an alternative data store or stores.
- You can see who uses the setting by tracing method calls.
Why it Doesn’t Really Solve The Problem
Well, let’s start out by pointing out that schema-less XML configuration isn’t really that bright an idea to begin with. I don’t think I’m the only one tired of the insane verbosity and lack of verification in XML. That in itself is relatively solvable by just reading all of the configuration settings on startup rather than when they’re first needed. It’s not elegant, but it works.
However, you’ve still got some fairly ridiculous things. First, your configuration class is a junkyard of settings for your app. Again, you can probably solve that by splitting it, but now you’ve got lots of configuration classes. And then you’re running into the risk of re-used settings again.
Let’s ignore that last problem and think a bit more about the users of these configuration classes. How many of them are there? Well, actually, there should only be one. If you’re observing the single responsibility principle, it’s fairly clear that any given data item should only have one purpose. If you’re remembering that data and code together is a fundamental principle of object oriented development, it’s pretty obvious that the class that is using the data item should be the configuration class itself.
Okay, aren’t we back to configuration chaos? Not quite, we’ve introduced some discipline. It helps to think about the responsibility of this new look configuration class? Basically, it’s now an abstract factory. The classes that originally used your configuration class now just take their configuration as constructor parameters. So, we’ve actually come full circle to the article that started it all.
Still Missing The Point
All of this is fine, but all I’ve really told you so far is that there are better pattevns for accessing AppSettings. But AppSettings is still a pretty useless bag of strings. Wouldn’t it be better to not have to write all of this wiring code? Wouldn’t it be better to say “set the connectionString parameter on the SessionFactory class to <<DEV>>” in the config file? Wouldn’t it be completely amazing if there was a framework that implemented a completely general version of this configuration class for you?
Well, actually, there is. Actually, there’s lots. AutoFac, Castle Windsor, NInject, Hiro, StructureMap (in no particular order) provide exactly this kind of functionality for .NET. PocoCapsule does it in C++, Spring and NanoContainer kicked off the whole concept in Java. It’s not as if this is even cutting edge anymore. All of them change the model: the configuration is pushed into your code, you don’t pull from it. All of a sudden, you don’t need to worry about writing configuration code at all.
If you ask me, the one thing training materials on the subject should really tell you is that the ConfigurationManager API is there’s a better way of handling configuration in your application.
And Merry Christmas. 🙂
*I toyed with the idea of calling this article “What Jeffrey doesn’t teach you about reading from .Net configuration” but rejected it as pointlessly provocative. The article is a good introduction to the problems of dealing with the .NET API and approaches for dealing with it. Jeffrey was blogging about IoC before I even got my head properly around the concepts.
CORRECTION: Changed Guice to PocoCapsule. As Mauricio points out, Guice is a Java container, not a C++ one. It’s harder to write an IoC container in a language without reflection support, however.