2

The Angular docs show an example of injecting a value (configuration object) using @inject in the constructor for the times when you aren't injecting a class.

https://angular.io/guide/dependency-injection#non-class-dependencies

I was able to get this to work, but I'm not sure I understand the point of this use-case. Because it's not a class creating instances--it's just a configuration object that's being read from, why wouldn't I just import it and read from it where I need to. I have to make an import to the class anyway even if I want to inject the value into the constructor.

Is this simply to make sure that the value is available at the time the class starts building since it's in the constructor?

I'm just not sure I'm seeing the value of the DI and feel I'm probably missing something.

indigo
  • 1,067
  • 4
  • 15
  • 26

2 Answers2

3

DI is mostly about testability. You can override providers in tests easily.
If you access values directly you would need to modify the code of the class or component you are testing in order to customize the behavior for tests.

There are other advantages like the ability to configure your application at a central place (where you specify the providers) to customize it for different use cases.

Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • 1
    Thanks! I can see the value for mocking and code organization, I just wanted to make sure I wasn't missing something more fundamental. It was just a bit of a contrived example for me with the configuration object in the docs. I suppose they wanted a simple example, but it just left me scratching my head a bit. – indigo Aug 30 '17 at 16:20
  • I also found this discussion helpful: https://stackoverflow.com/questions/41087531/angular2-dependency-injection-make-sense-or-its-just-overengineering – indigo Aug 30 '17 at 16:24
  • https://en.wikipedia.org/wiki/Inversion_of_control https://martinfowler.com/articles/injection.html is also strongly related. It allows to avoid tight coupling of classes. – Günter Zöchbauer Aug 30 '17 at 17:14
0

If it's first-party code, the primary concern is testability. If code belongs to public package or the units are being decoupled and moved to separate packages, it's extensibility as well. If config object is used in provider class:

import config from '...';

class SomeProvider {
    constructor() {
        this.config = config;
    }
}

it requires to subclass the provider to use another config object. If config is used directly instead of this.config in provider methods, the methods should be overridden. This can be avoided if config is a provider, too.

This is a big concern in public packages because developers didn't foresee that there will be reasons to extend this piece of code. As a result, the project needs to be forked instead of using framework capabilities to make it flexible without much efforts.

You never know when you'll need to extend or replace the configuration.

Estus Flask
  • 206,104
  • 70
  • 425
  • 565