Background

In recent days, the concept of dependency injection or inversion of control is much talked about in the object oriented world of programming. I decided to give an introduction to this concept for people who want to understand this concept with little effort and use it effectively.

Introduction

So, what is dependency injection anyway? Simply put, it is the capability of a consumer to consume a component without knowing in advance the specifics/origins of the consumed component.

Now, you would ask, what’s new about this? Isn’t this why we have interfaces? I will explain this more clearly by taking an example of a design pattern that is much closer to the dependency injection design pattern; that is object creation, or factory framework. Consider a typical Factory pattern, as shown in the figure below.

There is a subtle difference between the Factory pattern shown above and the truly desired object oriented abstraction. The fact that the class factory actually knows about the consumed class (which implements the desired interface that was originally requested by the consumer) breaks this abstraction and the plug and play feature. This is exactly where the dependency injection framework comes in.

Motivation

The motivation for the dependency injection framework comes from the concepts of "Inversion of Control" and extensibility. Applications, nowadays, are providing more and more extension points to enrich the functionality of solutions. Extended plug-ins, in such cases, really take on the control from the container that hosts them in the first place (hence the term "Inversion of Control"). Hence, dependency injection enables abstraction of dependencies at design time from the dynamic binding at runtime. This way, extension points can be instantiated, injected as properties or in the constructor of the dependent object, with dynamic configuration. A great example of such an application is Eclipse.

Dependency Injection Frameworks

In the dependency injection framework, the consumer specifies a set of dependencies that it requires to be fulfilled in order to perform an operation. During runtime, a configuration / declarative effort is required to specify the consumable objects that can fulfill a set of dependencies. An assembler / runtime component can then perform the necessary binding prior to code execution, or notify failure via exceptions. The following figure depicts this behavior.

Dependency injection frameworks was really made possible by new generation object oriented languages that support metadata access capabilities such as Reflection and dynamic code generation / loading. The idea, however, is much older, and can be seen in dynamic linked libraries, and even COM.

There are many frameworks that aid in dependency injection. I will discuss one of the major frameworks, known as Spring.NET. Spring.NET implements many proven design patterns that make building enterprise applications easier. But, I will just focus on the dependency injection part of Spring.NET.

A simple example of dependency injection using Spring.NET

Trust me, even sample examples that ship with Spring.NET aren’t simple. So, I decided to make a small startup example to demonstrate how we can use Spring.NET to solve the factory creation scenario discussed above.

For building this code, I used Visual Studio .NET 2008, along with Spring.NET binaries that I obtained from here.

I then created a sample console project called SpringDotNETExample, and added a reference to the Spring.Core assembly to the project (this assembly can be found in the bin folder of your Spring.NET installation directory; for me, it was c:\Program Files\Spring.NET 1.1.2\bin\net\2.0\debug\Spring.Core.dll).

The scenario is very simple. We have a generic interface ISayHello that has a string property SayHello, as follows:

At runtime, I want to bind my configuration to create WorldSayHello as a concrete implementation for ISayHello. But, this mapping will be transparent to my main program which will use the Spring.NET assembler to request an instance of the mapped object. For this example, I would assume that the main program requests this object via the key “ISayHelloInterface” that must correspond to the mapping.

To create the mapping, I created a mapping in my application configuration file, app.config. Following are the contents of this file. I have bolded the interesting parts of this file, rest are just Spring.NET essentials that are less interesting.

Now, my program simply requests the object mapped to the key ISayHelloInterface to obtain an implementation of the ISayHello interface. Notice that the mapping can be changed without compiling the code. This can provide immense versioning capabilities. Following is my main program:

Share

About the Author

Ashish worked for Microsoft for a number of years in Microsoft Visual Studio (Architect edition) and Windows Live division as a developer. Before that he was a developer consultant mainly involved in distributed service development / architecture. His main interests are distributed software architecture, patterns and practices and mobile device development.

Currently Ashish serves as a Technical Lead at RIM leading next generation BlackBerry media experience and also runs his own company MixModes Inc. specializing in .NET / WPF / Silverlight technologies. You can visit MixModes at http://mixmodes.com or follow it on Twitter @MixModes

In his free time he is an avid painter, hockey player and enjoys travelling. His blog is at: http://ashishkaila.serveblog.net