Elegant App Settings using Castle Dictionary Adapter Factory

Page content

Traditionally, settings in ASP.Net apps are stored AppSettings area of the app as a key-value store. More complex apps would create specific config sections. The app would then have a static settings wrapper that would read the content from the web.config.

I don’t know how many times I’ve seen this or variations of this.

1public static class Settings
2{
3    public static string SomeSetting
4    {
5        get { return ConfigurationManager.AppSettings["SomeSetting"] ?? string.Empty; }
6    }
7}

Reasons to avoid static settings class

Testability

By using static setting classes with app/web.config, you are restricting yourself (unless you do some further work) to a single key-value per project. Now what if you want to test the behaviour of your system with different settings values?

Dependency injection

With static settings class, you stick with a single specific implementation rather than an interface that can later injected with any implementation according to your needs.

Reasons to user static settings class

Access in the views

One major advantage of static settings classes is the ability to access your settings easily in the views. Extra code scaffolding would be required if dependency injection is used.

The best of both worlds

The way to get best of both worlds is to have an abstract settings interface, that is then passed on to the static settings class. Even better, using Castle Windsor IoC, you can use DictionaryAdapterFactory to load and parse your settings via factory.

First declare the IApplicationSettings interface

1public interface IApplicationSettings
2{
3    string TestUrl { get; set; } 
4}

Create a static class to mirror the settings. Or include the settings that you only need in your views / static context

 1public static class Settings
 2{
 3    private static IApplicationSettings _settings;
 4 
 5    public static void InitSettings(IApplicationSettings settings)
 6    {
 7        _settings = settings;
 8    }
 9 
10    public static string TestUrl
11    {
12        get { return _settings.TestUrl; }
13    }
14}

Create the container and register the factory via DictionaryAdapterFactory (in your bootstrap or global.asax etc)

 1...
 2 
 3WindsorContainer container = new WindsorContainer();
 4container.AddFacility<Castle.Facilities.FactorySupport.FactorySupportFacility>();
 5 
 6container.Register(
 7    Component.For<IApplicationSettings>().UsingFactoryMethod(
 8        () => new DictionaryAdapterFactory()
 9             .GetAdapter<IApplicationSettings>(ConfigurationManager.AppSettings)));
10...

Remember to instantiate your static settings class with the IApplicationSettings (after you registered the factory)

1Settings.InitSettings(container.Resolve<IApplicationSettings>());

Have fun!