Inversion of Control (IoC) and Dependency Injection (DI) are two practices, patterns, techniques, that I have been very interested to take a look at in greater detail. I came across a tutorial (the tutorial) which goes over IoC and DI using the Castle Windsor Container (and Micro Container), part of the Castle Project. Two other similar implementations presented in the tutorial are Spring.NET and StructureMap, as well as Microsoft's ObjectBuidler DI framework. The ObjectBuilder framework is used in the Enterprise Library, and Composite UI Application Block (CAB), which is good enough for me to steer clear of it and try out the Windsor Container instead.
I have never really been impressed with the Enterprise Library, and the CAB seemed overly cumbersome. Granted, it has been over a year since I last looked at the CAB and EntLib in any great detail, so maybe things have gotten better. I know allot of people live and breath EntLib, but I'm trying to experience some other thoughts outside the typical Microsoft sphere, such as Alt.Net. Microsoft is starting to catch onto the Alt.Net movement especially with the introduction of the Asp.Net MVC framework, a topic for a future post.
Part I
So what exactly is inversion of control? It helps if you consider how an application is traditionally written and define what "control" means. "Control" can be thought of as adding references to various assemblies, declaring instances of specific specific classes by calling the appropriate constructor and passing in parameters. The tutorial refers to this as a "canonical programming process". Now if we take the opposite, or invert the control, then our application does not reference specifically assemblies and does not instantiate concrete classes. Instead your application makes use of interfaces or abstract classes and relies on a framework to instantiate the classes as needed. This is commonly referred to as the Hollywood Principle, and what post on design patterns would be complete without a link to Martin Fowler.
The tutorial talks about another design principle, which is the separation of concerns (SoC). Separation of Concerns states that a component should do only one task, and do it very well. In the tutorial's example application, the functionality to download HTML data should be separated from the logic to parse the HTML itself. By separating the two pieces and applying IoC, if a new, faster algorithm for parsing was written, it could be swapped out with the original with no modification to the application. Under a traditional model, you would have to edit the single class, change the parsing routine, and then recompile the class and application. Then what happens when management says, "well the first algorithm was slower, but it was written by the boss's nephew....".
The tutorial defines a component as: "... a small unit of reusable code. It should implement and expose just one service, and do it well. In practical terms, a component is a class that implements a service (interface). The interface is the contract of the service, which creates an abstraction layer so you can replace the service implementation without effort."
The power of an Inversion of Control framework does not become apparent until you have components with dependencies on other components, each with their own dependency. The Castle project refers to it's IoC as a container which is offered in two versions. The first exposes the core IoC functionality and is called the MicroKernel. In the simplest of terms, you add components by specifying a key (ID), type and assembly to load. You then ask the container for an instance, which it returns, loading all required dependencies. The 2nd version of the container, Windsor, extends the Micro Kernel and is used most often. It adds supports for generics to reduce casting and external configuration (app.config and web.config) options to name a few.
Part II:
Part III
Party IV
Questions:
Conclusion:
I can't wait to try out the Micro Kernel and Windsor Container in a project. The flexibility is phenomenal, and the decorator pattern makes it extremely easy to extend functionality. I only took a quick look at the StructureMap and Spring.Net, and they have some interesting features which need further investigation.
Disclaimer The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.