Wednesday 12 November 2014

Castle Windsor IoC experiment

I use Castle Windsor for dependency injection at work. The application I work on is a large e-commerce application with many moving parts. I find a DI container such as Castle Windsor (Castle) essential considering the number of dependencies that needs to be resolved.

We use "feature" toggles to control what feature are turned on in Production. I think this is pretty common for any agile organisation. There are times, certain features are not ready and we "turn off" the feature so that the customer do not see it. Again, this is standard practice.

We register the dependencies in Castle using the fluent interface. As new features are developed, the number of dependency installation files increases. Taking a step back from this, I thought if we do not need a feature why its dependencies are registered in Castle in first place. I bet this is not an issue for Castle as there is no request to resolve a dependency. However I believe that if a features is "turned off" then it should not be present in Castle.

So I embarked on an experiment to see how this might work.

Problem description

We have the interface "IAnimal" that has multiple implementation "Bat", "Dog", "Cat" (different features). The idea is to register the correct type based on the feature that is currently enabled.

Potential solution

I used the following to register the dependencies in Castle.



There are no surprises here, I simply register types that implement "IAnimal" in the currently assembly. However what I have introduced here is an extension method. The idea is to provide the configuration that determines what dependencies needs to be installed in the container.
I also indicate that the "IAnimal"s that I find should be registered against "IAnimal" in Castle. (If you have used Castle, you know that there is "WithService.AllInterfaces()" that allows you to register types against all the interfaces that a dependency implements.

The extension method is below.

I use the "If" method to register each dependency if it is defined in the "config.Registrations". The key piece of information here is the "registration.UseWith". This defines in what context that the dependency should be used.

An example of an ordinary registration is as follows.

The data structure is pretty standard. It defines the feature key and what is and what is not to be used when a feature is turned on/off respectively.

The full code is in GitHub.

Issues and problems


Generally dependencies are registered at "startup". For an web application this means App_Start. This event is triggered at the start of the application and NOT on each request. What I am assuming in the above code is that the application will restart once a feature is turned on or off. I do not think this is the desired behavior. For a large scale application with thousands of users browsing at the same time, service downtime is completely taboo.

So to sum up, I am not convinced that the above solution is going to work for me. It has been a good learning experience going though documentation/Git repo to find out how "stuff" work.

In the next post, I am going to look at the next logical solution "TypedFactories".

Sorry to disappoint.  :-(