Click here to Skip to main content
Email Password   helpLost your password?

Introduction

In designing an object-oriented application, a major tenet of design is "loose coupling". Loosely, not meant for the pun, "loose coupling" means that objects should only have as many dependencies as is needed to do their job - and the dependencies should be few. Furthermore, an object's dependencies should be on interfaces and not on "concrete" objects, when possible. (A concrete object is any object created with the keyword new.) Loose coupling promotes greater reusability, easier maintainability, and allows you to easily provide "mock" objects in place of expensive services, such as a socket-communicator.

"Dependency Injection" (DI), also more cryptically known as "Inversion of Control" (IoC), can be used as a technique for encouraging this loose coupling. There are two primary approaches to implementing DI: constructor injection and setter injection. Obviously, at some point, something must be responsible for creating the concrete objects that will be injected into another object. The injector can be a parent object, which I'll call the "DI controller", or can be externalized and handled by a "DI container" framework. What follows is a brief overview of the various approaches for using dependency injection techniques.

Constructor Injection

Constructor Injection is the DI technique of passing an object's dependencies to its constructor. The below example includes a class, Customer, that exposes a method for retrieving every sales-order that the customer made on a particular date. Consequently, the Customer class needs a data-access object for communicating with the database. Assume, an OrderDao ("order data-access object") exists which implements the interface IOrderDao. One way that a Customer object can get this dependency is by executing the following within the: IOrderDao orderDao = new OrderDao();. The primary disadvantage of this is two-fold:

  1. the benefit of having the interface in the first place has been negated since the concrete instance was created locally, and
  2. OrderDao cannot easily be replaced by a mock object for testing purposes. (Mock objects will be discussed shortly.)

The aforementioned example follows:

public class Customer {
    public Customer(IOrderDao orderDao) {
        if (orderDao == null)
            throw new ArgumentNullException("orderDao may not be null");
        
        this.orderDao = orderDao;
    }
    
    public IList GetOrdersPlacedOn(DateTime date) {
       // ... code that uses the orderDao member

       //     get orders from the datasource ...

    }
    
    private IOrderDao orderDao;
}

In the example, note that the constructor accepts an interface; it does not accept a concrete object. Also, note that an exception is thrown if the orderDao parameter is null. This emphasizes the importance of receiving a valid dependency. Constructor Injection is, in my opinion, the preferred mechanism for giving an object its dependencies. It is clear to the developer invoking the object which dependencies need to be given to the Customer object for proper execution. But consider the following example... Suppose you have a class with ten methods that have no dependencies, but you're adding a new method that does have a dependency on IOrderDao. You could change the constructor to use Constructor Injection, but this may force you to change constructor calls all over the place. Alternatively, you could just add a new constructor that takes the dependency, but then how does a developer easily know when to use one constructor over the other. Finally, if the dependency is very expensive to create, why should it be created and passed to the constructor when it may only be used rarely? "Setter Injection" is another DI technique that can be used in situations such as this.

Setter Injection

Setter Injection does not force dependencies to be passed to the constructor. Instead, the dependencies are set onto public properties exposed by the object in need. As implied previously, the primary motivators for doing this include:

  1. supporting dependency injection without having to modify the constructor of a legacy class, and
  2. allowing expensive resources or services to be created as late as possible and only when needed.

The code below modifies the Constructor Injection example to use Setter Injection instead:

public class Customer {
    public Customer() {}

    public IOrderDao OrderDao {
        set { orderDao = value; }
        get {
            if (orderDao == null)
              throw new MemberAccessException("orderDao" + 
                             " has not been initialized");
            return orderDao;
        }
    }
    
    public IList GetOrdersPlacedOn(DateTime date) {
        //... code that uses the OrderDao public

        //... property to get orders from the datasource ...

    }
    
    // Should not be called directly;

    // use the public property instead

    private IOrderDao orderDao;
}

In the above example, the constructor accepts no arguments. Instead, the invoking object is responsible for setting the IOrderDao dependency before the method GetOrdersPlacedOn is called. With Constructor Injection, an exception is thrown if the dependency is not set immediately, i.e., upon creation. With Setter Injection, an exception isn't thrown until a method actually attempts to use the dependency. Make note of the fact that GetOrdersPlacedOn uses the public OrderDao property; it does not call the private orderDao directly. This is so that the getter method has an opportunity to validate if the dependency has yet been initialized.

Setter Injection should be used sparingly in place of Constructor Injection, because it:

  1. does not make it clear to the developer which dependencies are needed when, at least until a "has not been initialized" exception is thrown, and
  2. makes it a bit more difficult to track down where the exception came from and why it got thrown. With this said, Setter Injection can save on modifying a lot of legacy code when introducing new methods, and can provide a performance boost if the dependency is expensive or not easily accessible.

The Injectors

The next logical question is, what actually creates the dependencies that are to be injected into "injectees"? There are two appropriate places for adding creation logic: controllers and containers.

DI Controllers

The "DI controller" approach is the simpler to understand and implement. In a properly tiered architecture, an application has distinct layers for handling logic. The simplest layering usually consists of a data-layer for talking to the database, a presentation-layer for displaying the UI, and a domain-logic layer for performing business logic. A "controller" layer always exists, even if not well defined, for coordinating UI events to the domain and data layers, and vice versa. For example, in ASP.NET, the code-behind page acts as a rudimentary controller layer. More formalized controller-layer approaches exist: Struts and Spring for Java; Front Controller and Spring .NET for .NET. All of these approaches follow some form of variant of the Model-View-Controller pattern. Regardless of what you use as your controller, the controller is an appropriate location for performing Dependency Injection "wiring". This is where concrete objects are created and injected as dependencies. What follows are two examples of DI performed by a controller. The first is an illustrative example of "production code" - code that you'd end up deploying. The second is an example of "test code" - code that's used to test the application, but is not deployed and does not have the need to have a live database.

Controller code performing the dependency injection (e.g., from an ASP.NET code-behind page):

//... code performed when the controller is loaded ...


IOrderDao orderDao = new OrderDao();
// Using Setter Injection on a pre-existing customer

someCustomer.OrderDao = orderDao;
IList ordersPlacedToday = 
  someCustomer.GetOrdersPlacedOn(DateTime.Now);

...

Unit-test code performing dependency injection:

IOrderDao orderDao = new MockOrderDao();
// Using Setter Injection on a pre-existing customer

someCustomer.OrderDao = orderDao;
IList ordersPlacedToday = 
   someCustomer.GetOrdersPlacedOn(DateTime.Now);

One of the major benefits of using a DI-controller to inject dependencies is that it's straightforward and easy to point to where the creation is occurring. The drawback to using DI-controllers is that the dependencies are still hard-coded somewhere; albeit, they're hard-coded in a location that is often subject to frequent changes anyway. Another drawback is that now the DI-controllers themselves can't be easily unit-tested with mock objects. (Granted, a powerful tool such as TypeMock can do just about anything when it comes to injecting mock objects. But a tool such as TypeMock should be used only when absolutely necessary as it can lead to habits of not programming-to-interface. In fact, I'd recommend only considering the use of it on very difficult to test, legacy applications.)

In ASP.NET, I prefer to use the Model-View-Presenter (MVP) pattern, and have the ASP.NET code-behind page create dependencies and inject them to the presenter via Construction Injection. Additionally, I use UserControls as the View part of the pattern, so the ASP.NET code-behind acts purely as an MVP "dependency initializer" between the UserControls (View) and their presenters.

Another option to implementing constructor or setter DI is the use of an application container...

DI Containers

Inversion-of-Control/Dependency-Injection "containers" can be used to watch an application and inject dependencies whenever a particular event occurs. For example, whenever a Customer instance is created, it automatically gets injected with its needed dependencies. It's a strange concept at first, but can be useful for managing large applications with many service dependencies. Different container providers each have their own mechanism for managing dependency injection settings.

Spring .NET allows you to define dependency injections within an XML file. The following example Spring .NET XML uses Setter Injection to give an ASPX code-behind page its data-access object dependency:

<spring>
    <context type="Spring.Context.Support.WebApplicationContext, Spring.Web">
        <resource uri="config://spring/objects" />
    </context>

    <objects xmlns="http://www.springframework.net">
        <!-- Data Access Object that will be injected into ASPX page -->
        <object id="daoFactory" type="MyApp.Data.DaoFactory, MyApp.Data" />

        <object type="ViewDetails.aspx">
            <property name="DaoFactory"  ref="daoFactory" />
        </object>
    </objects>
</spring>

The ASPX code-behind simply exposes a public property called DaoFactory that "catches" the dependency whenever the page gets called. See Spring .NET's website for more details and more examples. For Java developers, be sure to check out Spring's website.

Many other containers exist, some of which don't require much XML management at all (for those of you that cringe at the sight of a 500 line XML file). For Java developers, take a look at Container Comparison for a good comparison of options. For .NET developers, the decision is simpler as fewer options exist. (Is that a good thing?) See Open Source Inversion of Control Containers in C# for some open-source options.

Unit Testing with Injected Mock Objects

The greatest benefits that I've experienced using DI are cleaner unit testing and greater portability. Portability is a given as most of the dependencies are on interfaces. But let's look at how DI can benefit unit testing as well. It is often the case that developers write unit tests against a live database. This is all well and fine, but it quickly brings the speed of a suite of unit tests to a crawl. To keep unit testing from becoming a drag, it needs to be easy to turn off slow unit tests that actually hit the database while still testing the business logic that depends on data access. Mock objects are perfect for doing just this. A mock object simulates the responses of an actual object, acting as if it's using a real resource. They're great for mocking access to a database, mocking calls to IO, mocking calls to a web service, etc.

The below code shows a mock data-access implementation of the IOrderDao interface used throughout the article:

public class MockOrderDao : IOrderDao {
    public Order GetOrderById(long orderId) {
        Order foundOrder = new Order();
        foundOrder.SaleDate = "1/1/06";
        foundOrder.ID = orderId;
        
        return foundOrder;
    }
}

This trivial, mock data-access object implements IOrderDao, and can therefore be passed to any object that's dependent on IOrderDao via Constructor or Setter injection. Now all your business logic can be tested without actually hitting the database. In my own test suite, I usually have a section that contains "real" database tests, and then pass mock database-access objects for testing my domain objects.

Additional References

You must Sign In to use this message board.
 
 
Per page   
 FirstPrevNext
GeneralGreat article!
Alan Balkany
6:37 18 Feb '10  
The clearest explanation of dependency injection I've seen! The examples are nice and simple, and they make the text understandable.
GeneralRe: Great article!
Billy McCafferty
7:05 18 Feb '10  
Thank you very much for the feedback. If it assists further, I invite you to read my most recent article on the subject at http://devlicious.com/blogs/billy_mccafferty/archive/2009/11/09/dependency-injection-101.aspx[^].

Enjoy!

Billy McCafferty
GeneralDependency Injection with Ninject for .NET
MD.Tanvir Anowar
20:32 23 Dec '09  
In the following article it's clearly describe how to do DI in .NET with Ninject framework (basic and short).
Dependency Injection with Ninject for .NET
GeneralS#arp-Architecture
Radim Köhler
6:32 18 Sep '08  
Thanks for this article.
And for your S#arp-Architecture. I would say that (your) solution of IoC with ConcreteTypeAttribute is more straightforward, clear and pure
than any 'sophisticated' IoC tool (like Spring.NET) can offer.
It helped me a lot.
GeneralDAO's are not accessible from codebehind directly when in different assembly?
AliasElias
12:40 4 Jul '08  
This is my current basic understanding of working with business objects/DAO classes.
- In your codebehind you have access to your domain objects: you have no access to your DAO's because the presentationlayer should not reference the DAO layer assembly.
- Inside your domain objects code you have access to your DAO's.

Now this occurred to me:
How can you create an instance of your DAO inside the codebehind when everything has its own assembly?
GeneralRe: DAO's are not accessible from codebehind directly when in different assembly?
Billy McCafferty
5:49 7 Jul '08  
This is all dependent on the underlying architecture of your application. One to consider is S#arp Architecture[^]. This facilitates a strong separation of concerns and very low coupling between the presentation, controller, data and domain layers.

Billy
GeneralRe: DAO's are not accessible from codebehind directly when in different assembly?
AliasElias
12:21 7 Jul '08  
I only write forms applications so I suppose S#arp is not an option for me, but thanks for your suggestion.
GeneralChales
kaken20
4:45 12 Jun '08  
Good article this quite well, what I see is that q confuse the term mock / stub.
Your class is not a mock(MockOrderDao) is a stub, I recommend this article(bottom)
A stub serves to replace a depedency on your system, a mock serves to validate whether the execution code to be correctly.....







Article http://martinfowler.com/articles/mocksArentStubs.html#TheDifferenceBetweenMocksAndStubs
AnswerRe: Chales
Billy McCafferty
4:48 12 Jun '08  
You're right! I wasn't clear myself about that when I wrote this article...I'll be sure to update it, accordingly. Thanks for bringing this to my attention!

Billy McCafferty
GeneralNice
mikeperetz
5:50 29 Dec '07  
Thanks for taking the time and sharing this knowlage with us. I am currently doing a lot of research on AOP and DI using Spring.Net - Your article helped put some stuff together.

Thanks.

"There are only 10 types of people in the world: Those who understand binary, and those who don't" More articles on my blog

GeneralThis article is really good!
OhadAs
9:06 20 Nov '07  
Very clear and summarized, with good examles!
QuestionHelp [modified]
kiran kulkarni
3:41 19 Sep '07  
i am testing an application in which a method A depends on other method B of same class. How do i test method A independently. Please help

Ex:
class calc
{
public int add(int a, int b)
{return a+b}
public int mul(int a, int b)
{return a*b}

public int AddMul(int a, intb)
{return (a+b) + mul(a,b)}
static void Main()
{
calc calculator = new calculator();
calculator.AddMul(4,5);
}
}
Now suppose i am testing AddMul method independently(without depending on add method). How can i mock add method. Please help with full code for the above example
Thanks in advance
waiting for replay
Kiran

Knowledge grows by sharing.


-- modified at 5:58 Thursday 20th September, 2007
GeneralMethod Injection
Ronald Band
15:10 11 Jul '07  
Nice article.

I was wondering if method injection should be considered in your article (as mentioned by like Dr Herbie).

I tend to use method injection so that the object receiving the injection does not need to store it, which further reduces dependencies.

Regards,
Ronald Band.

The challenge of software engineering is to keep it simple and easy to change later as change is the only constant. Visit www.wiselittlebirdie.com.

GeneralRe: Method Injection
Jon Davis
3:15 30 Jul '07  
Wouldn't that just be passing in a delegate as a dependency?
GeneralStructureMap - Another mature IoC framework
Lars Nilsson
22:25 18 Jun '07  
Another mature IoC framework is StructureMap[^] by Jeremy D. Miller.


GeneralDI Container with NHibernate?
symon15@hotmail.com
12:43 4 Feb '07  
Hi Billy,

Great article - it certainly explains an often complex issue in a nice straight forward manner. I have a question though; how does dependency injection work with ORM (in my case NHibernate)? If you use a DI container (Castle Windsor for example) and wire up the domain objects for either constructor or setter injection will NHibernate respect these wirings?

For example, if you've persisted an object and have then at some future time used the ORM to load the object will the dependencies be re-injected into the loaded objects?

Cheers mate,

Symon.
AnswerRe: DI Container with NHibernate?
Billy McCafferty
12:43 5 Feb '07  
In my own work, I don't use Container DI to inject dependencies into the business objects themselves. Alternatively, I inject them into the controller/presenter layer of an MVP separation of logic. In almost every case, I try to keep my business objects with as little dependency on services as possible and stick strictly to domain rules. But obviously, there are situations in which business objects need service dependencies, such as to an email utility. In this case, I use Container DI to give the controller the email utility and then manually pass the email utility to the business object from the controller/service layer. Since it happens rarely - in my current app, anyway - this setup doesn't create a lot of overhead and still provides a high level of service-independent testability.

Billy
GeneralCircular dependencies
DrGUI
12:29 26 Apr '06  
I mostly use constructor injection, but I remember using setter injection once when I had a circular dependency...so I just thought I'd add that it's useful when you have circular dependencies (through interfaces of course, otherwise you'd want to make them into the same class!)
Generalthat's "tenet," not "tenant"
u neek
8:53 26 Apr '06  
after all, what good is a great vocabulary if you can't use it to correct people? Wink
GeneralRe: that's "tenet," not "tenant"
Billy McCafferty
8:58 26 Apr '06  
lol...hear hear!
GeneralRe: that's "tenet," not "tenant"
Billy McCafferty
10:38 26 Apr '06  
Fixed! Thanks for the heads up.
GeneralCAB?
Josh Smith
8:53 19 Apr '06  
Great article! I've been wondering about DI for some time now; it's nice to finally have an idea of what it means. Smile

Do you know what type(s) of dependency injection the new Composite UI Application Block (CAB) uses? I've heard that CAB uses DI to promote loose coupling, but haven't yet had a chance to investigate further.

Thanks,
Josh
GeneralRe: CAB?
Billy McCafferty
9:09 19 Apr '06  
I only do ASP.NET and am not familiar with the details of the CAB. But A cursory Google search brought back a couple of resources that may prove useful:

* http://realworldsa.dotnetdevelopersjournal.com/dependency_injection_generics_enterprise_library_20_composit.htm[^]
* http://www.agileprogrammer.com/oneagilecoder/archive/2006/01/03/10564.aspx[^]

Billy
GeneralRe: CAB?
Diederik Krols
5:07 26 Apr '06  
I guess this is what you're looking for: Dependency Injection and Microsoft Windows Forms-A walkthrough using Microsoft's Composite UI Application Block[^]

Diederik


GeneralRe: CAB?
Josh Smith
15:37 26 Apr '06  
Thank you, Diederik.

Josh


Last Updated 18 Apr 2006 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2010