The ConfigurationManager facade class is a solid member of the base class library. It allows one to access the application settings, connection strings and other configuration sections from configuration files.
The problem with the facade class is that its members are static and there doesn’t seem to be an easy way to mock the internal implementation. Thus, testing becomes complicated as the internal implementation is bound to the *.config files.
A natural way to resolve this difficulty is to provide another facade but this time a mockable one. You start with an interface :
and then you let it be injected into the facade
where the default implementation points back to the old facade
This approach lets you provide any implementation and inject it into the new facade. And this is the major drawback of this approach – it forces the client code to switch to the new facade or at least to the new interface. For a large code base this means that a lot of code which uses the old facade must be inspected and manually switched to the new facade.
But, hey, this is not a big issue – you could think – I do it once and at least from the very moment I have a correct architecture of the system.
Alas, there is just another minor drawback. The new interface is a custom interface which means that it has to be provided in a custom class library. Suppose then you have two large code bases, X and Y, developed independently. The X code base solves the configuration manager problem by providing the new interface and the new facade. The Y code base solves the same problem by providing its own, yet another interface with yet another facade.
And then, you try to merge X and Y in the new composite solution, Z. For this, you need two different implementations of injected configuration providers (or better, a implementation and one adapter so that the actual implementation is provided only once).
All these major and minor issues made me rethink the issue once again. I started to find a way to inject a custom implementation of the configuration provider into the existing facade, the ConfigurationManager class. And, surprisingly, there is a way.
You see, if you decompile the ConfigurationManager facade, it turns out that internally all it does it is uses an internal provider of type System.Configuration.Internal.IInternalConfigSystem (in fact, in contrary to its name, the interface is not internal!). And the facade has an explicit method to inject this provider, ConfigurationManager.SetConfigurationSystem! The only subtle issue is that the injection method is, for an unknown reason, internal.
All this means that the architecture of the existing facade is prepared for an injectable provider but for some unknown reason someone has blocked the explicit possibility to inject a provider.
And of course, this is not a real issue if you have the reflection.
What you need then is to have a way to inject your own implementation somewhere early in the app lifecycle (the composition root perhaps). With a help of a concrete implementation, all you have to do is to provide actual settings:
Now I can have my custom configuration injected and there is no need to rewrite the existing code: