Rich Newman

July 21, 2007

Introduction to Dependency Injection (Introduction to CAB/SCSF Part 3)

Filed under: .net, beginners guide, Dependency Injection, introduction — richnewman @ 12:26 am

Introduction

This article is actually part 3 of an introductory series of articles on Microsoft’s Composite Application Block (CAB) and Smart Client Software Factory (SCSF). However, this particular article will only talk about dependency injection in general terms and not discuss the CAB/SCSF. Part 5 of the series will address dependency injection in the CAB. Part 4 of the series expands the discussion here by talking about inversion of control (IoC) and dependency inversion.

Dependency Injection

Dependency injection as a general concept is explained far better than I could do it by Martin Fowler at http://www.martinfowler.com/articles/injection.html. However, in short it is a means of allowing a main class to use a second, dependent class without directly referencing that class. Some external entity will provide the second class to the main class at runtime – it will ‘inject’ the ‘dependency’. Obviously to be useful the second class will need to implement an interface that the main class knows about.

The aim of this is to let us change the behaviour of our class structure by changing which second class is injected into the main class. Because the main class has no hard dependency on the second class this can be done at runtime. Thus our code is very flexible, easy to modify and loosely coupled.

Class Diagram

The class diagram looks something like this:

Dependency Injection Class Diagram

MainClass contains a reference to an object that implements IDependentClass, and can thus call the DoSomethingInDependentClass method on that object. DependentClass1, DependentClass2, and DependentClass3 implement the interface.

Some client code will then create the appropriate dependent class and tell the main class to use it (via the interface). It’s easiest to understand this via some example code, which I’ll demonstrate below.

Strategy Pattern?

In many ways this is the classic Gang of Four Strategy pattern with a twist. The class diagram above is very similar to the usual one given for the strategy pattern: see http://www.dofactory.com/Patterns/PatternStrategy.aspx (don’t worry if you don’t know the strategy pattern at this stage though). The difference is that with dependency injection exactly which class is going to be provided as the dependency (strategy) is often left to configuration at runtime. That is, it can be abstracted out of the code entirely.

In the Spring framework, for example, XML configuration files can be used to specify which class gets created and used. This is an extreme example of deciding which class to use at runtime: you can change the dependencies without changing the compiled code at all.

However, there are some reasons for not using external configuration files to specify these dependencies: it makes it difficult to debug, and you’re probably not going to want to change application behaviour via a configuration file in any case. Dependency injection frameworks in general will allow you to specify your injection in code (Spring allows this).

Dependency Injection Example

We can easily create an example that does this using .NET. Full code for all these examples is available for download.

Firstly we create an interface that will be used to call our dependent class:

    public interface IDependentClass
    {
        void DoSomethingInDependentClass();
    }
 

Then we create dependent classes that implement this interface to do something. Which one of these classes will actually be used will only be decided at runtime based on a setting in the App.Config file:

    public class DependentClass1 : IDependentClass
    {
        public void DoSomethingInDependentClass()
        {
            Console.WriteLine("Hello from DependentClass1: I can be injected into MainClass");
        }
    }
 
    public class DependentClass2 : IDependentClass
    {
        public void DoSomethingInDependentClass()
        {
            Console.WriteLine("Hello from DependentClass2: I can be injected as well, just change App.Config");
        }
    }

Now we create a class that will use the dependent classes, calling their functionality via the interface. This ‘main’ class has no knowledge of the dependent classes types, only of the interface that they implement:

    public class MainClass
    {
        IDependentClass dependentClass;
        public IDependentClass DependentClass { get { return dependentClass; } set { dependentClass = value; } }
 
        public void DoSomething()
        {
            dependentClass.DoSomethingInDependentClass();
        }
    }
 

Now we need some code that will use this structure. Clearly we need to instantiate the main class and tell it (using the interface) which dependent class to use. We can then call the functionality on the main class.

        static void Main(string[] args)
        {
            // Get the correct dependency based on configuration file
            IDependentClass dependency = GetCorrectDependency();
 
            // Create our main class and inject the dependency
            MainClass mainClass = new MainClass();
            mainClass.DependentClass = dependency;
 
            // Use the main class, the method references the dependency
            // so behaviour depends on the configuration file
            mainClass.DoSomething();
 
            Console.ReadLine();
        }
 

Finally we need some code in GetCorrectDependency() that decides which dependent class we are going to use, and instantiates it. We do this by examining the ‘ClassName’ setting in App.Config, and instantiating that using Activator.CreateInstance:

        static IDependentClass GetCorrectDependency()
        {
            string classToCreate = System.Configuration.ConfigurationManager.AppSettings["ClassName"];
            Type type = System.Type.GetType(classToCreate);
            IDependentClass dependency = (IDependentClass)Activator.CreateInstance(type);
            return dependency;
        }
 

The App.Config file is as below:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <appSettings>
    <add key="ClassName" value="DependencyInjection.DependentClass1" />
  </appSettings>
</configuration>

So we can compile this code and run it as above and it will output the message in DependentClass1. If we then just change the configuration file so that the ClassName value is DependencyInjection.DependentClass2 and re-run the code will output the message in DependentClass2.

Note that what is powerful about this code is we could write a DependentClass3, with new behaviour, and use it by changing the configuration file without the need to change any of the existing code.

Types of Dependency Injection

Martin Fowler’s article talks about three different types of dependency injection: constructor injection, interface injection and setter injection. The example above uses setter injection: we give the main class its dependency via a setter in the line:

mainClass.DependentClass = dependency;

In constructor injection we give the main class its dependency in the constructor. With interface injection we define another interface that the main class will implement that sets the dependency.

I have reworked the example above for both constructor injection and interface injection. As you can see these are relatively trivial changes in this simple example.

Full C# code for these examples is available.

This series of articles is continued in part 4, which discusses inversion of control.

About these ads

19 Comments »

  1. I’m trying to get up to speed with CAB and SCSF fast and have found your articles to be very useful. As you have mentioned there is nothing that provides a simple explanation of these topics until now. I’ve found all three parts invaluable, and look forward to part 4 (hope it’s soon).

    Comment by Rich — July 31, 2007 @ 9:19 pm

  2. Great article. I was confused with dependency injection. Thanks for keeping it so simple. Keep the good work up and thanks.

    Regards
    Irfan

    Comment by Mirza Irfan Baig — October 8, 2007 @ 5:48 am

  3. Great series of articles, a great resource to explain novices about the ideas behind CAB and how to use it. I appreciate very much your effort.

    Comment by Giovanni Mazza — October 18, 2007 @ 9:16 pm

  4. Awesome work.
    A real gr8 article from startup to completes indepth implementation.

    Gr8 job:)

    Comment by Ujjwal Sinha — October 23, 2007 @ 12:05 pm

  5. Hi,Its really gr8.Good way to explain.Thanks a lot.

    Comment by Krish. — November 26, 2007 @ 8:39 am

  6. I was so confused with wht dependency injection is all bout.. and this article clears all my doubts on the same.. Thanks :)

    Comment by kirthika — December 4, 2007 @ 10:38 am

  7. WOW! I’ve been trying to find time to teach myself CAB for the past two years. Everytime I gave up because I never found clear/good tutos. Yours is A-B-S-O-L-U-T-E-L-Y limpid. I’ve understood more in 30 minutes reading till this part than in 2 years reading tons of tutos, doc, forum post.
    Thank you very much for sharing your understanding.

    Comment by KDave — March 8, 2008 @ 4:52 pm

  8. Thanks for the great series.

    I just wanted to let you know the link to the code is broken, other than that great article.

    Keep up the good work.

    Thanks,

    B

    Comment by Burt — March 19, 2008 @ 3:02 pm

  9. Thanks for your good article, I think you’ve described it better than The Great Martin Fowler!
    Simple & Easy & Enough

    Comment by Behdad Khoshbin — April 8, 2008 @ 10:00 am

  10. Dependency Injection made easy. Just what we need. Thanks for the good writeup.

    Comment by Klaus — April 8, 2008 @ 9:33 pm

  11. I agree you explained way better than The Great Martin Fowler

    Comment by Bill — October 9, 2008 @ 1:49 am

  12. The Fowler’s DI pattern is just confusing. It’s does not add anything more new than waht the Stategy pattern offers except more complications for configurating the code at run time. Of course, this is an anti pattern like the whole CAB practice.

    Comment by somisko — November 7, 2008 @ 1:33 pm

  13. Great article , helped a lot in doing my job in better manner

    Comment by sreedhar — July 11, 2009 @ 5:44 am

  14. Really very good article on SCSF. Your entire series is awesome..

    Many Thanks,
    Hari.

    Comment by Hari Prasad — July 24, 2009 @ 10:55 am

  15. These three articles are great. Now I am starting to get it!

    Thanks so much,

    Gil

    Comment by Gilbert — October 6, 2009 @ 9:06 pm

  16. Absolutely well axplained and demonstated.
    Thank you

    Comment by Sam — December 5, 2009 @ 9:16 am

  17. vegna ekki:)

    Comment by knirmAmiree-tool — January 17, 2010 @ 9:00 pm

  18. Awesome Good job

    Comment by Anupama — June 30, 2010 @ 2:20 pm

  19. GREAT TUTORIAL, well nicely explained the way how a beginner would need :)

    People like you should come to teach. The MSDN sucks all high level stuffs.

    Comment by Rama — June 14, 2011 @ 6:02 am


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

The Shocking Blue Green Theme. Create a free website or blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.

Join 81 other followers

%d bloggers like this: