The term software entropy is coined and the definition of it can be found here. I would like you to take into consideration the term configuration entropy.
Because of the increased complexity and forever changing requirements the way we write software has changed. In the past we could try and “one up” each-other by coding the same piece of logic in every project we worked on. This option has become impractical and dangerous. Dangerous because we tended to write half baked software that was just not up for the challenge. And to be honest I do not want to write a data access layer or DAL everytime, I just want to solve problems in my problem domain and not in all others that happen to be in my way.
To make the long story short: we are having more and more configuration in our applications. If you have to work on a compiled language you will notice quite quickly that once that a peace of code leaves the safe area of your test environment it usually developes some problems. And usually that results in an recompile and redeploy… So this is quite a big intensive put more “stuff” into configuration files.
So what does this mean? This means that you will reach a point where the configuration becomes more, and more complex than your actual code. The unit testing world has already proven that unit tests are part of our code and that they deserve the same tender attention and care as code itself. The same goes for all of that configuration. If you do not constantly watch after all the configuration out here you will get overrun. And when this happens you will have a BIG problem.
When you can’t tell where those mysterious values are coming from then my friend you are really at the heart of the configuration entropy zone. And getting this situation under control will require quite some effort. So we should avoid it at any cost.
In my experience the best way to do this to divide and conquer. This is achieved by following the following steps:
- Ignore the existence of the appSettings section in the app.config/web.config file
- Configure once, use often
- Write custom configuration sections!! <- How this is done later on
- Lose the idea that all configurations are stored in one file
- All configuration that can be put in a separate file should be put in a separate file
- Do not place configuration in code <- only partially true
Ignore the existence of the appSettings section
The developers in Redmond were so nice as to give as a common and easy to use place where to put all our application configurations. This sounds great but is really a curse. Why? Because after some time you will notice that it gets hard to manage. You will spend more cognitive effort trying to remember how the configuration key is called and to validate if the configuration value is really what you expect. In the configuration API all is an object by default so there is no easy way to determine if the value given is really a number or just a bogus string.
And from my personal experience this section tends to get big (100+ entries) and environment management gets harder and harder!
Write custom configuration sections
Because we ignore the appSettings configuration section we have to get a suitable substitute. And luckily we have! They are called custom configuration sections. The main advantage of them is that they are type safe. Remember the type validation you had to with the appSettings?
This is the right time to notice that there are two ways of doing this:
- The “old” way:
In the old days the custom configuration manager just contained an event handler in which you could/should pars an XML node that contained your configuration section. This is not the prefered way but still gets the job done.
- The “new” way:
Today we have a more elegant solution to the problem. Now you have a typed interface to the configuration values in the XML file. Sadly this means sticking to some limitations of this implementation.
What you want to provide is a custom configuration section for different configuration groups. So for instance all configuration values that have something to do with the configuration of the price calculation logic should be in a configuration group called “Price” or something like this.
A detailed introduction into the world of custom configuration sections will follow in one of the future posts.
Lose the idea that all configurations are stored in one file
In todays flood of configuration values it almost impossible to store all configuration values in one big file. But still this happens, the file in question is usually the web.config or the app.config file. Why? Because they are automagically created by the project wizard. This is not bad for some cases but if the configuration of your application gets really heavy you will feel the burn. Maintenance will become a nuisance because the file will be just to big to manage.
So what do we do about this? The simplest and most logical solution is to use an algorithm that we all learned in school: “Divide and conquer”. By this I mean that you should put all configurations that can be in own files into own files. The prime candidate for this are log4net and Spring.net. Both can be put in own configuration files quite easily.
What do you gain by this?
- The configuration does not clog your app.config or web.config file anymore, leaving room for more vital configuration to be there
- When you need to change the configuration (for example having different logging configurations for test and live) you do not have to manipulate a complex XML file but just replace a file which is much more easily done
- You have different components in different configuration files, thus eliminating the need to feverishly scroll and look for the right section of the configuration file.
I can not put enough emphasis on tis issue. Try to believe me that this is a good thing. Some people may complain that the configuration just got scattered all over the place and that refactoring is now harder to do because of the configuration dependencies. But in the long run the separation will improve you codling skills and help you keep the configuration under control while the project will grow and evolve.
Do not put configuration in code
This is only partially true. Why? Because this rule does not apply to interpreted languages like ruby, python, php (reluctantly calling it a language). Do not be mislead by this. Configuration entropy is as big an issue on the other side of the river as it is here.
So why does the rule not apply to the interpreted languages? Because the whole code is big configuration file. Some will scream now and call me a stupid moron. But thing about it for a minute. In my world the “definition” of a configuration is: A non-compiled part of the application with which the behavior of a routine can be changed without a recompile. And because interpreted languages are not compiled we can change anything in the source-code and continue.
But this is where the problems begin. Because there is virtually no penalty in changing the source-code itself configuration tends to get scattered all around the code. Making it hard to manage the changes made to it. And a clear environment configuration gets quite frustrating when you have to alter multiple files to get the job done. That is why event in those languages I suggest that configuration should be kept in as few places a possible.
Returning back to the world of compiled languages the picture changes. If we stick to my definition of a configuration then all configuration that is stuck in code can not be changed without recompiling the application. Making it quite useless.
The final words
So after this short trip in this topic of configuration entropy I would like you to remember the following:
- Configuration is part of your code, so treat it like this
- Divide and conquer, do not put all your eggs in one basket
- Do not leave configurations in compiled code