How dependency injection in Angular is useful since it doesn't solve anything apparently?

Viewed 1722

How this can improve my code? How it can remove dependency ? I still don't see any benefit of using this ?

@Component({ 
  selector: 'talk-list', 
  templateUrl: 'talks.html', 
  providers: [TalksAppBackend] 
}) 
class TalkList { 
  constructor(backend:TalksAppBackend) { 
    this.talks = backend.fetchTalks(); 
  } 
}

If i had used

TalksAppBackend t= new TalksAppBackend(); that would have been the same. Apart from syntactical difference how different it is?

Update:

Also, it's calling .fetchTalks(); that's not mocking. How its possible?

3 Answers

First of all, it's a bad question for StackOverflow. But it deserves the answer. So here is it.

If you don't use Dependency Injection

The main difference is that if you don't use DI (dependency injection) then your code MUST know how to create all of its dependencies. You may have tons of components using tons of services. The services may rely on other services, like TalksAppBackend may require HttpClient service. And your code must create dependencies for its dependencies. Like

TalksAppBackend t = new TalksAppBackend(new HttpClient())

And every your component must do that, creating a new instance of the TalksAppBackend and an instance of HttpClient. And if later the TalksAppBackend will require some logging service, you must update manually all your components to instantiate all the deps for TalksAppBackend. Such code is hard to maintain and it uses more memory than it should because it doesn't share instances.

If you use Dependency Injection

You just specify the module or a component which is responsible for creating instance of desired dependency. It will take care of it's dependencies as well. You components may just specify the desired class TalksAppBackend to be injected and should not care about whether or not it requires HttpClient or Logger or whatever. The DI does that job. And you have a fine control over it: a global service which is provided by a module will be instantiated just once. So your components can share the same instance. And if you want to you may provide it on a component level so that many instances may be created and children components will have access to the only one instance that is needed.

And this approach also opens a way to mock dependencies and provide not the real TalksAppBackend service but rather a mock with fake answers that does not require network communication and running back-end to test if your component interprets the results accordingly. And you can do it without modifying the code of your component. So in this approach the component is focused for doing the thing it should do ONLY.

There are many benefits of it

  1. code with new key word is hard to test in a large application.
  2. important: consider you are instantiating a class with new keyword. And after few day you want to change/add parameters to dependent class constructor. Then you need to change your code wherever you have used the instance of the same class. this will be a huge deal in an large project
  3. Instances of dependencies created by a class that needs those dependencies are local to the class and cannot share data and logic

It's good question. There alot of benefits of it. You can read about it on the same subject in AngularJS here: What are the benefits of AngularJS dependancy injection?

But for me, the key is the tests. If you do unit tests of this component, you can inject easilly a mock of TalksAppBackend and then isolate the component from their dependency in a unit test. By doing TalksAppBackend t= new TalksAppBackend(); in the code, you will not be able to do unit test on it.

Related