Monday, October 27, 2014

Dependency Inversion Principle and Dependency Injection


The Dependency inversion principle is one of the five S.O.L.I.D principles of object oriented programming and design which were popularized by Robert Cecil Martin better known as Uncle Bob through the publication of his books and articles.

Uncle Bob is also the person who initiated the 2001 meeting of the group that eventually came up with the agile software development methodology and the creation of the agile manifesto.

Why Dependency Inversion

If the dependency inversion principle is adhered to while designing classes that interact with each other, these classes will end up having lower coupling, lower coupling between classes makes them more welcoming to changes and extensions as changes and modifications to one class would not force changes upon the other classes that it interacts with.


There are several ways of implementing dependency inversion in the context of software development. but I will explain this using the more common method of dependency injection.

Dependency injection itself can be implemented in three different ways, constructor injection, property injection and method injection.  the most common method is constructor injection and in my opinion this is the preferred way as the class you are constructing requests the dependency up front and without it being provided the dependency, it cannot be instantiated.

Take the following example, which can be a very common scenario in a Asp.Net MVC eCommerce site ,where a list of items is retrieved by a controller through the use of a repository in order to be shown inside a view.


as visible in the above diagram and the below code snippet, in this scenario the ItemController depends on a concrete implementation of ItemRepository in order to be able to function.


    public class ItemController : Controller
    {
        private ItemRepository _itemRepository;
 
        public ItemController()
        {
            _itemRepository = new ItemRepository();          
        }
 
        public ActionResult Index()
        {
            IList items = _itemRepository.GetAllItems();
 
            return View(items);
        }
    }


the main problem in the above scenario is that if we wanted to create unit tests for our controller we would have to provide it with a concrete implementation of the ItemRepository.
The ItemRepository accesses the database in order to retrieve the items, and that would cause the test to take some time to complete. this might not be an issue if there is only one or two tests that you need to run each time a change has been made to your class but if you have tens or hundreds of tests in a project you will be wasting development time.
its generally accepted that tests should be able to run fast and that they should be run in isolation of different parts of the system. the dependency in the above controller would not allow us to achieve this.

In order to be able to overcome the above problem we will use a technique called constructor injection. In constructor injection the dependency is passed through into the constructor of the dependent class as an interface.


    public class ItemController : Controller
    {
        private IitemRepository _itemRepository;
 
        public ItemController(IitemRepository itemRepository)
        {
            _itemRepository = itemRepository;
        }
 
        public ActionResult Index()
        {
            IList items = _itemRepository.GetAllItems();
 
            return View(items);
        } 
    }

In our updated controller above we are now depending on an interface called IitemRepository instead of a concrete implementation of the ItemRepository.

the reason for introducing the interface is that we can implement a mock version of the itemRepository which does not access the database, and pass it to our tests and our code will still work.

By introducing the interface and injecting the dependency we have decoupled our controller from the itemRepository.

No comments :

Post a Comment