Configuration is an important part of most large scale applications. It’s also a distinct concern the details of which we wish to hide from the rest of our system. I address this by defining an interface that provides the configuration values. By using such an interface we break the coupling between the configuration system and the rest of the system and enabled some more interesting scenarios.

In a standard case you may have a configuration section and some configuration elements. In my example we define some interfaces:

public interface IExampleConfiguration
{
    IExampleComponent ConfigurationComponent { get; }

    string SomeString { get; }
}

public interface IExampleComponent
{
    int SomeProperty { get; }
}

We would have a matching configuration section for IExampleConfiguration and a configuration element for IExampleComponent. Note that IExampleConfiguration has the property ConfigurationComponent that is of type IExampleComponent. The configuration section and element look like this:

public class ExampleConfigurationSection : ConfigurationSection, IExampleConfiguration
{
    private const string ConfigurationComponentKey = "configurationComponent";
    private const string SomeStringKey = "someString";

    private static readonly ConfigurationPropertyCollection _properties = new ConfigurationPropertyCollection
        {
            new ConfigurationProperty(ConfigurationComponentKey,
                typeof(ExampleComponentConfigurationElement),
                null,
                ConfigurationPropertyOptions.None),
            new ConfigurationProperty(SomeStringKey,
                typeof(string),
                null,
                ConfigurationPropertyOptions.None),
        };

    protected override ConfigurationPropertyCollection Properties
    {
        get { return _properties; }
    }

    public IExampleComponent ConfigurationComponent
    {
        get { return (IExampleComponent) this[ConfigurationComponentKey]; }
        set { this[ConfigurationComponentKey] = value; }
    }

    public string SomeString
    {
        get { return (string) this[SomeStringKey]; }
        set { this[SomeStringKey] = value; }
    }
}

public class ExampleComponentConfigurationElement : ConfigurationElement, IExampleComponent
{
    private const string SomePropertyKey = "someProperty";

    [ConfigurationProperty(SomePropertyKey, DefaultValue = 0, IsRequired = true, IsKey = false)]
    public int SomeProperty
    {
        get { return (int) this[SomePropertyKey]; }
        set { this[SomePropertyKey] = value; }
    }
}

(I don’t recommend copying this blindly, read the documentation)

What we see here is that the configuration section exposes a property that is of type IExampleComponent but the property type itself is set to ExampleComponentConfigurationElement, which is the implementation of this interface.

We can now inject IExampleConfiguration into things that require configuration and have no coupling to the configuration system. For configuration based on the .NET configuration infrastructure we can do this by having the dependency injection container obtain the interface from the ConfigurationManager. For example using StructureMap I can do something like:

initialise.ForRequestedType<IExampleConfiguration>()
    .TheDefault.IsThis((IExampleConfiguration)ConfigurationManager.GetSection("example"));

This will retrieve the configuration section example and supply it whenever IExampleConfiguration is required (assuming the configuration file is correctly specified to have the section example provided by ExampleConfigurationSection).

My code is now independent of the configuration infrastructure. This will likely make testing easier as supplying configuration files for tests is annoying, fragile and doesn’t easily support varying the configuration. It certainly makes getting the configuration slightly easier as the configuration section name is only needed in one place. But it’s not particularly remarkable.

Where it gets interesting is the realisation that by breaking the coupling with the configuration infrastructure I can now provide the configuration implementation in any way that I wish. The .NET configuration infrastructure is flexible and has a number of useful features (such as supporting encryption of configuration information). However it isn’t appropriate for all scenarios. I may wish to use a different configuration source which may not be known at the time I’m writing my code (this is unlikely, but work with me here). I may wish to intercept calls to the configuration and change things around (although I wouldn’t recommend it).

I may also wish to substitute in a configuration that is defined in fixed classes based on my environment. I’ve been using this recently on a project which has two websites that share significant functionality but need to have the behaviour of this functionality tailored to their particular requirements. This includes such things as controlling which details need to be gathered in the various business processes and controlling sections of the process flow. I have defined a configuration interface that includes boolean properties for the various decisions that need to be made. Each site has its own implementation of the interface that returns the appropriate value for each property as defined by the requirements of the site with which it is associated. By defining multiple properties I get finer control as well as more readable code.

In the setup code for each site I then configure the dependency injection framework (StructureMap, although the DI framework used is not important in this usage) to return the appropriate implementation for that site. This is simpler than an equivalent implementation using the .NET configuration infrastructure. It is also less error prone to deploy as the appropriate configuration to use is baked into the website. As such we don’t need to worry that the site will display incorrect details or have an incorrect process due to a mistake in an XML configuration file that may be easily overlooked.

This relates to my post on the need to configure things by adding the question of when something needs to be configured. In this case I do need to configure the common functionality but this configuration can happen at compile time. Using the standard configuration infrastructure and doing the configuration at deployment is therefore sub-optimal as I am introducing a concern I could already have handled. By doing the configuration at compile time I reduce the number of times that I need to consider the setup. I also reduce the differences between the application as tested in my test environment(s) and deployed to production. As the configuration is hard coded into the relevant binaries I have the capacity to detect errors that would affect production in an environment I could not otherwise do so in. This is because using the XML configuration files would allow the value to be set correctly in test and incorrectly in production, something I have now prevented.

I have also been experimenting with using fluent APIs to perform some configuration that may be performed at compile time. This approach is useful as the configuration API for framework and infrastructure components where these have configuration that may be defined at compile time. I’m calling my limited efforts in this space semi-fluent until I get a decent handle on this approach. Once I have done so a blog post may appear on this topic. Or it may sink without trace, only time will tell.