sharp bites

standing on the shoulders of giants

AltNerdDinner: Part 2. Rich Man's Dependency Injection

This is part 2 of the AltNerdDinner Series.

The classes in NerdDinner use dependency injection (constructor injection, to be more precise), which is a form of Inversion of Control that allows you to break the dependencies between classes, minimizing coupling (i.e. a Good Thing ™). Instead having classes with direct dependencies  on other classes, and instantiating them directly, classes are dependent on interfaces, and the concrete implementation is injected via the constructor, in this case, or via a setter in the case of setter injection. Constructor injection is preferred for required dependencies, as it makes dependencies more explicit, and setter injection is usually reserved for optional dependencies.

Using this technique, the responsibility of providing the dependencies is delegated to the calling object (hence the term Inversion of Control).

Poor Man’s Dependency Injection

The problem with the NerdDinner codebase is that, besides the constructor that accepts the required dependencies, they added a default constructor that news up those dependencies. Here is an example:

public DinnersController() : this(new DinnerRepository())
{
}

public DinnersController(IDinnerRepository repository) {
dinnerRepository = repository;
}


This may look like a good compromise. You get the decoupling needed to run your tests (by means of the constructor accepting parameters) and you are also able to instantiate you classes calling the default constructor, without the added complexity of an IoC container. However this technique is considered an anti-pattern (although not everybody agrees) leading to many headaches. By adding this constructor we’re almost at square one again. Our classes are still coupled, and if we need to add new dependencies, we’ll have to go hunting around to fix all the constructor calls.



If I were a rich man



So now you are convinced to use an IoC container, you can have a look this container guidelines by Jimmy Bogard. He may not consider his recommendations as best practices, but I do (and so should you, IMHO). I picked Castle Windsor as my framework of choice. As usual, there are plenty of alternatives. Even though the API is not the cleanest of all the frameworks, I favored Windsor because it is very mature, is widely adopted, it also supports .NET 2.0, and has good integration with NHibernate. It also is the container used in S#arp Architecture, which is something I will probably end up using. Otherwise, my choice would be StructureMap.



In order to use Windsor, you have to reference on your project Castle.Core, Castle.MicroKernel and Castle.Windsor. To ease the configuration of the container, I also downloaded MvcContrib (which I was planning to use anyway) and added a reference to MvcContrib.Castle.



This is the code needed to register the controllers and the Repository.



private void RegisterComponents()
{
_container = new WindsorContainer();
ControllerBuilder.Current.SetControllerFactory(
new WindsorControllerFactory(_container));
_container.RegisterControllers(Assembly.GetExecutingAssembly());
_container.Register(
Component.For<IDinnerRepository>()
.ImplementedBy<InMemoryDinnerRepository>());
}


To allow the creation of the controllers by the MVC framework, you need to supply a ControllerFactory that can instantiate them, as they now take dependencies on their constructors. MvcContrib provides one for Windsor, as well as the method RegisterControllers to, guess what, registering all the controllers in a specified assembly. I also registered my DinnerRepository, so that Windsor can resolve the references to it.

Comments