Click here to Skip to main content
15,869,940 members
Articles / Programming Languages / C#

Dependency Injection Frameworks

Rate me:
Please Sign up or sign in to vote.
0.00/5 (No votes)
31 Oct 2011CPOL4 min read 16.4K   11   1
An introduction to Dependency Injection.

Background

In recent days the concept of dependency injection or inversion of control is much talked about in object oriented world of programming. I decided to give an introduction of this concept to 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/origination of the consumed component.

275884/image_thumb1.png

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 dependency injection design pattern; that is object creation or factory framework. Consider a typical factory pattern as shown in the figure below.

275884/image_thumb2.png

However, there is a subtle difference between the factory pattern shown above and 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 plug and play feature. This is exactly where dependency injection framework comes in.

Motivation

The motivation for dependency injection framework comes from the concepts of "Inversion of Control" and extensibility. Applications now a days are providing more and more extension points to enrich 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 dynamic binding at runtime. This way extension points can be instantiated, injected as properties or in constructor of the dependent object with dynamic configuration. A great example of such an application is Eclipse (www.eclipse.org).

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 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. Following figure depicts this behavior.

275884/image_thumb3.png

Dependency injection frameworks really was made possible by new generation object oriented languages that supported 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 framework known as Spring.NET (http://www.springframework.net/). Spring.NET implements many proven design patterns that makes building enterprise applications easier. But I will just focus on 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 factory creation scenario discussed above.

For building this code I used Visual Studio.NET 2008 along with Spring.NET binaries that I obtained from http://www.springframework.net.

I then created a sample console project called SpringDotNETExample and added reference to 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:

C#
namespace SpringDotNETExample 
{ 
    public interface ISayHello 
    { 
        String SayHello { get; } 
    } 
}

I then created a class WorldSayHello that implements ISayHello as following:

C#
namespace SpringDotNETExample    
{     
    public class WorldSayHello : ISayHello     
    {        
        public string SayHello     
        {     
            get { return "Hello Friend!"; }     
        }     
    }     
}

At runtime I want to bind my configuration to create WorldSayHello as concrete implementation for ISayHello. But this mapping will be transparent to my main program which will use Spring.NET assembler to request instance of mapped object. For this example I would assume that main program requests this object via 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.

XML
<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
   <configSections> 
      <sectionGroup name="spring"> 
        <section name="context" 
          type="Spring.Context.Support.ContextHandler, Spring.Core" />   
       <section name="objects" 
         type="Spring.Context.Support.DefaultSectionHandler, Spring.Core" /> 
     </sectionGroup> 
   </configSections> 
   <spring> 
      <context> 
         <resource uri="config://spring/objects"/> 
      </context>  
   <objects xmlns="http://www.springframework.net">   
      <description>An example that demonstrates simple IoC features. 
      </description> 
      <object name="ISayHelloInterface" 
         type="SpringDotNETExample.WorldSayHello, SpringDotNETExample"/> 
   </objects> 
   </spring> 
</configuration>

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

C#
using System; 
using Spring.Context; 
using Spring.Context.Support; 

namespace SpringDotNETExample 
{ 
  class Program 
  { 
    static void Main(string[] args) 
    { 
       IApplicationContext ctx = ContextRegistry.GetContext(); 
       ISayHello hello = (ISayHello)ctx.GetObject("ISayHelloInterface"); 
       Console.WriteLine(hello.SayHello); 
    } 
  } 
}

Running the program yields the following output. :)

Hello Friend!
Press any key to continue . . .

In my next articles, I will discuss some more advanced concepts in dependency injection such as constructor injection. So stay tuned!

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) MixModes Inc. | Research In Motion
Canada Canada
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

Comments and Discussions

 
QuestionVery nice Pin
prayag022428-Jan-15 1:58
prayag022428-Jan-15 1:58 
Hi,
Thanks for the simple yet complete example, really helpful !

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.