There are two big benefits of DI: Decoupling and Testing.
Let’s first start with Decoupling. Consider your application has a logger functionality which helps to log errors, warning, etc. in some central place. This central place can be a file, event viewer, database, etc.
function FileLogger()
{
this.Log = function () {
alert("File logger");
};
}
function EventLogger()
{
this.Log = function () {
alert("Event viewer logger");
};
}
Now let’s say you have a Customer
class that wants to use the Logger
classes. Now which Logger
class to use depends on configuration.
So the code of Customer
is something as shown below. So depending on the configuration, Customer
class either creates FileLogger
or it creates EventLogger
object.
function Customer($scope, Logger)
{
$scope.Logger = {};
if (config.Loggertype = "File")
{
$scope.Logger = new FileLogger();
}
else
{
$scope.Logger = new EventLogger();
}
}
But with DI, our code becomes something as shown below. The Customer
class says he is not worried from where the Logger
object comes and which type of Logger
objects are needed .He just wants to use the Logger
object.
function Customer($scope,$http, Logger)
{
$scope.Logger = Logger;
}
With this approach, when a new Logger
object gets added, the Customer
class does not have to worry about the new changes because the dependent objects are injected by some other system.
The second benefit of DI is testing. Let’s say you want to test the Customer
class and you do not have internet connection. So your $http
object method calls can throw errors. But now, you can mock a fake $http
object and run your customer class offline without errors. The fake object is injected using DI.