Dependency Injection is a common technique in Software Engineering where instead of your objects creating dependency or creating one via factory, you pass the dependencies into the object externally. Sounds confusing yet? Good. I will explain further.
A Simple Example
Consider this example of querying products from a repository:
Right now, I have a Product class that consists of GetAllProducts method that will call the RepositoryFromTextFile method GetAll.
So, we are good and my RepositoryFromTextFile class is reading nicely from a text file and the RepositoryFromTextFile is decoupled from the method and passed to constructor for instantiation. However, what if I decided to share with my friends the source code and they felt that reading from a text file is not the best method and decided to read it from let’s say static repository, SQL Database or pool from external service? They had to rewrite my code, such that they have to change RepositoryFromTextFile to maybe RepositoryDB, RepositoryMemory, RepositoryExtService in Product class. This may sound alright if there is only 1 simple change, but it will be disaster when you need to change huge classes to reflect the latest changes.
So, in this case, we can see that Product is dependent on both IRepository interface and RepositoryFromTextFile class. I would rather that Product is dependent on just the IRepository interface. So, how do I improve this?
Inversion of Control
Inversion of Control is a design principle where it inverts the control of a system as compared to procedural programming. IoC is often used to increase the modularity and make an application extensible.
By inverting the instantiation to the caller, we have the following class:
So, now my friends do not need to change my RepositoryFromTextFile to their own desired repository. This is an example of how IoC works.
However, the problem doesn’t end here. What if the program is calling a service calling the product, followed by calling the repository?
The problem starts when you have so many classes to invert and this will end up in a behavior of Poor Man’s Dependency Injection.
This is when you would want to inject the dependency on these classes. By using some DI framework such as StructureMap, Ninject, AutoFac, it will make use of the DI container to make your work easier. As an example, in ASP.NET Core project template, dependency injection is already included by default via
Microsoft.Extensions.DependencyInjection package. You can inject dependency by just adding either the following under ConfigureServices method in your startup.cs class: