BlackWaspTM

This web site uses cookies. By using the site you accept the cookie policy.This message is for compliance with the UK ICO law.

Design Patterns
.NET 1.1+

Dependency Injection

Dependency injection is a technique used in object-oriented programming languages. It promotes loose coupling of components by passing dependencies to an object, rather than having an object instantiate its own dependencies.

What is Dependency Injection?

Object-oriented design can lead to the creation of structures containing components that are dependent upon other classes, known as dependencies. In such situations, you may decide to instantiate a class's dependencies from within the dependent class, using the new keyword.

As an example, consider the code below. This defines a class, named "PaymentTerms", that holds the details required to calculate the monthly payments for a loan. The class includes three properties that define the price of an item being purchased, the deposit being paid and the term of the agreement. The GetMonthlyPayment method calculates the monthly fees using a PaymentCalculator object. This calculator is a dependency of PaymentTerms and is initialised when an object is instantiated.

NB: The operation of the PaymentCalculator class has been oversimplified but this is unimportant for the subject of this article. The properties are defined using C# 3.0 automatically implemented property syntax. For earlier versions of the .NET framework you should expand these and include a backing store.

public class PaymentTerms
{
    PaymentCalculator _calculator = new PaymentCalculator();

    public decimal Price { get; set; }
    public decimal Deposit { get; set; }
    public int Years { get; set; }

    public decimal GetMonthlyPayment()
    {
        return _calculator.GetMonthlyPayment(Price, Deposit, Years);
    }
}


public class PaymentCalculator
{
    public decimal GetMonthlyPayment(decimal Price, decimal Deposit, int Years)
    {
        decimal total = Price * (1 + Years * 0.1M);
        decimal monthly = (total - Deposit) / (Years * 12);
        return Math.Round(monthly, 2, MidpointRounding.AwayFromZero);
    }
}

One of the key problems with the above code is the instantiation of the PaymentCalculator object from within the PaymentTerms class. As the dependency is initialised within the containing class, the two classes are tightly coupled. If, in the future, several types of payment calculator are required, it will not be possible to integrate them without modifying the PaymentTerms class. Similarly, if you wish to use a different object during automated testing to isolate testing of the PaymentTerms class, this cannot be introduced.

Dependency injection reduces the problem of tight coupling by removing the instantiation of dependencies from a dependent class. Instead, pre-constructed objects are passed to a dependent object at some time before they are required. In this article we will consider three types of dependency injection. These are interface injection, setter injection and constructor injection. Each provides a class's dependencies using a different manner.

Implementing Interface Injection

Interface injection allows the dependencies of a dependent object to be provided by calling a known method. The method is declared within an interface that is implemented by the dependent class. The dependencies are passed using the method's parameters at a time before the dependency is required.

Interface Injection

The UML class diagram above describes an implementation of interface injection. The items in the diagram are described below:

  • IDependent. This interface defines the method that is used to inject one or more dependencies.
  • Dependent. This is the dependent class that implements the IDependent interface to allow objects to be injected using a known method. In the UML, the dependency is stored in a private field.
  • IDependency. This interface describes the members provided by all dependencies that implement it. By using an interface, the dependencies can easily be substituted with other types, or by fakes, stubs or mocks for testing purposes.
  • Dependency. This class represents a dependency that may be injected into a dependent object.

The following shows the basic code for interface injection implemented using C#.

public interface IDependency
{
    void SomeMethod();
}


public class Dependency : IDependency
{
    public void SomeMethod()
    {
        Console.WriteLine("Dependency.SomeMethod() called");
    }
}


public interface IDependent
{
    void InjectDependency(IDependency dependency);
}


public class Dependent : IDependent
{
    IDependency _dependency;

    public void InjectDependency(IDependency dependency)
    {
        _dependency = dependency;
    }

    public void CallDependency()
    {
        _dependency.SomeMethod();
    }
}
12 September 2010