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)
{
}
}