Use Dependency Injection To Simplify Application Settings

We've all seen and written code that accesses data from our app.config or web.config file.  We'll throw some simple settings in there:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <appSettings>
        <add key="enableLogging" value="true" />
        <add key="startDate" value="12/1/2010" />
        <add key="baseFee" value="157.50" />
    </appSettings>
</configuration>

And then we'll use the ConfigurationManager to pull the data out when we need it:

public class Foo
{
    public void DoSomething()
    {
        bool enableLogging = Convert.ToBoolean(ConfigurationManager.AppSettings["enableLogging"]);
        DateTime startDate = Convert.ToDateTime(ConfigurationManager.AppSettings["startDate"]);
        decimal baseFee = Convert.ToDecimal(ConfigurationManager.AppSettings["startingFee"]);
    }
}

Now that Inversion of Control and Dependency Injection are part of my everyday development, I don't do it this way anymore.  It's messy and doesn't allow me to easily plug in different values during testing.

These days, I create a simple interface for my application settings:

public interface IApplicationSettings
{
    bool EnableLogging { get; }
    DateTime StartDate { get; }
    decimal BaseFee { get; }
}

And create an implementation of this interface that pulls data from app.config:

public class AppConfigSettings : IApplicationSettings
{
    public AppConfigSettings()
    {
        this.EnableLogging = Convert.ToBoolean(ConfigurationManager.AppSettings["enableLogging"]);
        this.StartDate = Convert.ToDateTime(ConfigurationManager.AppSettings["startDate"]);
        this.BaseFee = Convert.ToDecimal(ConfigurationManager.AppSettings["startingFee"]);
    }
 
    #region IApplicationSettings Members
 
    public bool EnableLogging { get; private set; }
    public DateTime StartDate  { get; private set; }
    public decimal BaseFee { get; private set; }
 
    #endregion
}

I register my types with my IoC container.  During production, dependency injection takes over and automatically gives me my AppConfigSettings instance.  For testing, I generate a mock IApplicationSettings.  And using these settings just got a whole lot cleaner:

public class Foo
{
    public Foo(IApplicationSettings applicationSettings)
    {
        
    }
}

5 Comments

Comments have been disabled for this content.