Decoupling your configuration file using the Castle project
Frederik Prijck, a friend and blogger extraordinaire, wrote a blogpost a few days back about the importance of decoupling your configuration file from the rest of your application. Frederik covers the topic pretty thoroughly and I wanted to write a post on how I achieve the level of decoupling he talks about. To provide an easy and simple practical example that I use in application that are deployed to production.
By writing this I am achieving a first for my blog. I'm writing an addition to a post I did not write while allowing the one to complete the other. Which is pretty cool :).
Decoupling a configuration file
As this post is meant to be an addition upon Frederiks post, you should read 'Decoupled from the configuration file' first. It is clearly written and I agree with it completely. So do that now (don't worry, I'll wait a bit ^^).
At the end of his post, Frederik writes about the 'IMailConfig' interface, which allows access to the configuration stuff you need through an abstraction and without depending on concrete implementations. Frederik provides a 'HardcodedMailConfig' class, which is fine as an example. But in many cases you'll just want a way to access your application settings without using the ConfigurationManager class.
To achieve this I would rather not write a concrete implementation that I fill with ConfigurationManager.AppSetting['someAppSettingValue'] references. This would results in maintaining more files and more code altogether. You'll also depend on strings (AppSettings keys) to get the values, which is never a good idea.
Introducing Castle Core
Castle Core is a project containing auxiliary tools and components that are commonly needed by developers. One of those tools is the DictionaryAdapter. This little gem provides on the fly generation of strongly typed wrappers around untyped dictionaries, or chunks of XML (like config file).
Implementing the bits and bytes
To start, we'll include the Castle.Core nuget package. You can do this by running the following command in the Package Manager Console:
Install-Package Castle.Core
Once you have the Nuget package installed you can easily register an instance of the IApplicationConfig interface. Since we are now working with all sorts of application settings (not just mail stuff) we will not be using the IMailConfig example interface any more. A more global approach just makes more sense for this example.
The example below uses Autofac, but any IOC framework will do.
var _factory = new DictionaryAdapterFactory();
var _settings = _factory.GetAdapter<IApplicationConfig>(ConfigurationManager.AppSettings);
builder.RegisterInstance(_settings).As<IApplicationConfig>();
You can now inject the IApplicationConfig interface in your classes that depend on its configuration. If you want to add, alter or delete an AppSetting, simply update your interface and your configuration file. Castle will automatically load the altered settings in the DictionaryAdapter.
The IApplicationConfig interface can look something like this:
public interface IApplicationConfig
{
string ServiceName { get; }
bool Enabled { get; }
PersistanceEnum Persistance { get; }
}
On a side-note, the DictionaryAdapter has a build in parsing mechanism for booleans, ints, enums, etc. So just add the correct value types in your interface, Castle.Core will take care of the rest.
The corresponding AppSettings section looks like this:
<appSettings>
<add key="ServiceName" value="servicename" />
<add key="Enabled" value="False" />
<add key="Persistance" value="InMemory" />
</appSettings>