Enabling DI/IoC for noobs – Part 1

The powers that be agree that Dependency Injection (DI) & Inversion of Control (IoC) patterns help applications become more component-based, easier to maintain & better designed and are open to unit testing & mocking.

But how does one really use DI/IoC in their application to get the advantages aforementioned?

The following series of article provides a step-by-step guide to structure code for working with DI & then implementing IoC for noob programmers.

This article is the first of this series & provides an introduction to DI.

What is Dependency Injection?

Dependency Injection (DI) is a mechanism to inject dependencies into code such that the piece of code can consume the injected dependency without having knowledge of the construction or lifetime of the injected dependency.
In other words, DI in object-oriented computer programming is a technique for supplying external dependency (ie. a reference) to a software component – that is, indicating to a part of program which other parts it can use (Wikipedia, 2010)

Let us understand the definition by breaking down the definition into smaller parts.

What is a dependency?

Consider the following lines of code:

public class AccountController{

    private readonly IAccountRepository _repository;

    public AccountController (
        IAccountRepository repository ) {

        if(repository == null)
            throw new ArgumentNullException("repository");

        _repository = repository;
    }

    public ActionResult Login( string userName,
        string password ){

        var isLoggedIn = _repository.DoLogin(userName,
                                 password);
        return isLoggedIn
            ? View("AccountInfo")
            : View("Login");

    }
}

In the above sample, we can say that the class AccountController has a dependency on a type implementing the IAccountRepository interface ie. for the AccountController to perform its functionality, it would need a valid instance of IAccounRepository to be passed.

One key aspect to note is that we are not passing the concrete class of IAccountRepository, but instead passing in an interface. The advantage of doing this is the AccountController is not dependent on the concrete class, but only an implementation of IAccountRepository. In other words, the AccountController has a dependency on the IAccountRepository implementation.

What is Injection?

In the code sample above, we now know that the AccountController has a dependency on the IAccountRepository. The manner in which we can provide this dependency is known as injection.

One of the simplest ways to do this is:

var account_controller = new AccountController(
       new WindowsAccountRepository());

We could have a WindowsAccountRepository implemented as:

public class WindowsAccountRepository
    : IAccountRepository
{
    public bool DoLogin(
        string userName,
        string password
    ){
        // some code to do login by checking against the Active Directory
    }
}

But then at a later date, if you decided that you would like to have a custom implementation for account management & want to store the information in a database, all you would need to do is create a concrete class for your repository implementing the IAccountRepository & inject that into the constructor of the AccountController like below:

public class CustomAccountRepository
    : IAccountRepository
{
    public bool DoLogin(
        string userName,
        string password
    ){
      // some code to validate against a database
    }
}

Consuming this new class would look like:

var account_controller =
    new AccountController(
        new CustomerAccountRepository()
    );

This way, the complexity of the implementation of IAccountRepository is abstracted away from AccountController. But, AccountController is able to use the behavior exposed via the interface while the consumer of the AccountController is free to inject a concrete implementation of IAccountRepository.

Wrap up

In this first article, we defined dependency injection & what it means using a simple code sample. We have seen how we can replace the dependency by injecting a concrete implementation at the time of consumption.

In the next article, we will look at writing unit tests on the code we have just written & explore the benefits of DI in the context of unit testing.

Comments & suggestion always welcome.

References:

Wikipedia 2010, Dependency Injection – http://en.wikipedia.org/wiki/Dependency_injection

Advertisements

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