Friday, July 9, 2010

Dependency Injection, Problem statement & solution through an example in C#.

Dependency Injection:

In Which scenario we should opt for Dependency Injection???

Problem

You have classes that have dependencies on services or components whose concrete type is specified at design time. In this example, ClassA has dependencies on ServiceA and ServiceB. Figure 1 illustrates this.
Ff649378.4722b85b-ac16-4e68-b46d-c70e52adcd72(en-us,PandP.10).png
Figure 1
ClassA has dependencies on ServiceA and ServiceB
This situation has the following constraints:
  • To replace or update the dependencies, you must change your classes' source code.
  • The concrete implementation of the dependencies must be available at compile time.
  • Your classes are difficult to test in isolation because they have a direct reference to their dependencies. This means that these dependencies cannot be replaced with stubs or mocks.
  • Your classes contain repetitive code for creating, locating, and managing their dependencies.

Forces

Any of the following conditions justifies using the solution described in this pattern:
  • You want to decouple your classes from their dependencies so that these dependencies can be replaced or updated with minimal or no changes to your classes' source code.
  • You want to be able to write classes that depend on classes whose concrete implementation is not known at compile time.
  • You want to be able to test your classes in isolation, without using the dependencies.
  • You want to decouple your classes from being responsible for locating and managing the lifetime of dependencies.

Solution

Do not instantiate the dependencies explicitly in your class. Instead, declaratively express dependencies in your class definition. Use a Builder object to obtain valid instances of your object's dependencies and pass them to your object during the object's creation and/or initialization. Figure 2 illustrates this.
Ff649378.360cdd41-4418-4fff-9dee-fc6140458c1d(en-us,PandP.10).png
Figure 2
Conceptual view of the Dependency Injection pattern
Ff649378.note(en-us,PandP.10).gifNote:
Typically, you express dependencies on interfaces instead of concrete classes. This enables easy replacement of the dependency concrete implementation without modifying your classes' source code.
The following are the two main forms of dependency injection:
  • Constructor injection
  • Setter injection
In constructor injection, you use parameters of the object's constructor method to express dependencies and to have the builder inject it with its dependencies. In setter injection, the dependencies are expressed through setter properties that the builder uses to pass the dependencies to it during object initialization.

Implementation Using the Unity Application Block

The Dependency Injection pattern can be implemented in several ways. The Unity Application Block (Unity) provides a container that can be used for dependency injection. For more information about the Unity Application Block, see Unity Application Block.

Example

The NewsReaderPresenter class of the Stock Trader Reference Implementation (located at StockTraderRI.Modules.News\Article\NewsReaderPresenter.cs) uses constructor dependency injection to obtain a valid instance of a view that implements the INewsReaderView interface. The class definition is shown in the following code.
public class NewsReaderPresenter : INewsReaderPresenter
{
    private INewsReaderView readerView;

    public NewsReaderPresenter(INewsReaderView view)
    {
        this.readerView = view;
    }

    public void SetNewsArticle(NewsArticle article)
    {
        readerView.Model = article;
    }

    public void Show()
    {
        readerView.ShowView();
    }
}
Because the NewsReaderPresenter class uses dependency injection to obtain its dependencies, its dependencies can be replaced with mock implementations when testing. The following test methods, taken from the fixture file StockTraderRI.Modules.News.Tests\NewsView\NewsReaderPresenterFixture.cs, show how the NewsReaderPresenter class can be tested in isolation using mock implementations to replace the classes' dependencies and verify behavior.
[TestMethod]
public void ShowInformsViewToShow()
{
    var view = new MockNewsReaderView();
    var presenter = new NewsReaderPresenter(view);

    presenter.Show();

    Assert.IsTrue(view.ShowViewWasCalled);
}

[TestMethod]
public void SetNewsArticlesSetsViewModel()
{
    var view = new MockNewsReaderView();
    var presenter = new NewsReaderPresenter(view);

    NewsArticle article = new NewsArticle() { Title = "My Title", Body = "My Body" };
    presenter.SetNewsArticle(article);

    Assert.AreSame(article,view.Model);
}

Liabilities

The dependency injection pattern has the following liabilities:
  • There are more solution elements to manage.
  • You have to ensure that, before initializing an object, the dependency injection framework can resolve the dependencies that are required by the object.
  • There is added complexity to the source code; therefore, it is harder to understand.

Related Patterns

The following patterns are related to the Dependency Injection pattern:
  • Inversion of Control. The Dependency Injection pattern is a specialized version of the Inversion of Control pattern where the concern being inverted is the process of obtaining the needed dependency.
  • Service Locator. The Service Locator pattern solves the same problems that the Dependency Injection pattern solves, but it uses a different approach.

More Information

For more information on the Dependency Injection pattern, see the following:

5 comments:

Unknown said...

Another nice related article could be found at :
http://www.dotnetspark.com/kb/266-inversion-control-ioc-and-dependency-injection.aspx

Unknown said...

Most of the times we get confused between Dependency Injection with Factory Pattern!!!

DI is a type of abstraction layer on factories, but they also provide benefits beyond abstraction. A true factory knows how to instantiate a single type and configure it. A good DI layer provides the ability, through configuration, to instantiate and configure many types.

Obviously, for a project with a few simple types that requires relatively stable business logic in their construction, the factory pattern is simple to understand, implement, and works well.

OTOH, if you have a project containing numerous types whose implementations you expect to change often, DI gives you the flexibility through its configuration to do this at runtime without having to recompile your factories.

Unknown said...

With dependency injection the client does not need to get its dependencies on its own, its all prepared beforehand.

With factories, someone has to call those to get the generated objects over to the place where they are needed.

The difference lies mostly in this one line where calling the factory and fetching the constructed object is done.

But with factories you have to write this 1 line everywhere you need such an object. With DI you just have to create the wiring (relation between usage and created object) once and just rely on the presence of the object afterward everywhere. On the other side, DI often requires a bit more (how much depends on the framework) work on the preparation side.

Unknown said...
This comment has been removed by the author.
Unknown said...

Another nice article, which shows DI implementation from scratch (Through Unity framework).

http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/2009/08/10/rough-notes-on-unity.aspx