Frequently when reviewing code I see one of my pet hates appear and that’s a direct dependency on the ConfigurationManager. The ConfigurationManager provides a way to access values in the WebApp.config. Yet, like any dependency, they generally bite you at some point – generally when you attempt to write the test.
Let’s imagine that our web.config has a value like below:
EnableNewsletterSignup = “false”
This value defines if we should hit the live web service. During developmentsystest we don’t want this to happen, however we do in UAT and Live. As a result, our code will generally look like this:
public bool Signup(string email)
{
if (!Boolean.Parse(ConfigurationManager.AppSettings[“EnableNewsletterSignup”]))
return false;
return true; // technically this would go off to an external web service
}
Simple, yet with multiple problems
Firstly, we have a magic string value which relates to the key in the config. If we wanted to change this value we would have to perform an error-prone SearchReplace. Secondly, we have to manually parse the string value to a boolean – again, this is error prone as we’ll need to protect against bad data. This additional logic hides the true intent of what the method is meant to be doing which increases complexity. To make matters worse, we have a major problem when it comes to testability.
The configuration manager will automatically detect the config file based on the executing assembly, this means that your test assembly’s App.config needs to match your implementation’s (web.)config with all the values pre-configured for testing purposes. Having pre-configured values offers you very limited flexibility and in the example above we would be unable to test both paths (without our tests changing the value directly)? If we had multiple possible paths, this would cause us a very real problem.
This week I came across the issue were I required an AppSetting value. Not wanting to face the issues above I looked for help.
Thankfully, help’s available
The Castle Dictionary Adapter removes these problem for us. Given an interface and a dictionary of values, the adapter will create an object with all the properties populated for us. Our interface will match the settings in our config file.
public interface IApplicationConfiguration
{
bool EnableNewsletterSignup { get; set; }
}
The same implementation mentioned before becomes this, with a dependency on the above interface instead of the concrete ConfigurationManager. Notice our ‘if’ statement now uses a strongly typed property without all the noise associated.
class NewsletterSignupService
{
private readonly IApplicationConfiguration _configuration;
public NewsletterSignupService(IApplicationConfiguration configuration)
{
_configuration = configuration;
}
public bool Signup(string email)
{
if (!_configuration.EnableNewsletterSignup)
return false;
return true; // technically this would go off to an external web service
}
}
Testing!
The real advantage arrives when you look at the problem from the testing point of view. Because it’s an interface, we can use Rhino.Mocks to produce a stub, allowing us to test using any possible value.
var stubConfig = MockRepository.GenerateStub
stubConfig.EnableNewsletterSignup = true;
We also no-longer need to maintain the App.Config as everything is driven by stub config objects, making life easier all round.
The next level comes when you use it with an IoC framework such as Castle Windsor. When an object defines a dependency on IApplicationConfiguration, they will be provided with an object created via the DictionaryAdapterFactory with the values coming from our actual AppSettings.
WindsorContainer container = new WindsorContainer();
container.AddFacility
container.Register(
Component.For
() => new DictionaryAdapterFactory().GetAdapter
As a result of implementing the adapter together with it’s use in Windsor we have more control, less complexity and a more maintainable solution going forward.
But it’s not only for AppSettings, the Castle Dictionary Adapter works on a number of different directories and collections meaning you no longer need to index into them using strings. If you want to know more, then CastleCasts has a great screencast on this at http://castlecasts.com/Episodes/3/Show/dictionary-adapter
In order to implement this in your own codebase, Castle Dictionary Adapter is currently a separate single assembly with no external dependencies that you can download from http://www.castleproject.org/castle/download.html
Going forward, it will be part of Castle Windsor 2.5 with some interesting improvement as discussed at http://devlicio.us/blogs/krzysztof_kozmic/archive/2010/07/05/castle-windsor-2-5-the-final-countdown-beta-1-released-and-core-dynamicproxy-dicitionary-adapter.aspx
The code for the above example is available at http://gist.github.com/486603