I have been trying to figure out how the (DI) Dependency Injection work in Angular2. I ran into lots of problem/issue every time when I tried to Inject a service/or class into my components.
From different googled articles, I need to either use providers: []
in the Component configuration, or sometimes I need to use @Inject()
in my constructor or inject directly in the bootstrap(app, [service])
? I've also seen some articles want me to put @injectable
decorator.
For example: to inject Http, I only need to import{Http}
and put Http in the providers, but for FormBuilder, I need to use @Inject()
in constructor.
Is there any rule of thumb for when to use what? Could you please provide some example code snippet? Thank you :-)
Dependency injection in Angular2 relies on hierarchical injectors that are linked to the tree of components.
This means that you can configure providers at different levels:
- For the whole application when bootstrapping it. In this cases, all sub injectors (the component ones) will see this provider and share the instance associated with. When interacting, it will be the same instance
- For a specific component and its sub components. Same as before but for à specific component. Other components won't see this provider. If you redefine something defined above (when bootstrapping for example), this provider will be used instead. So you can override things.
- For services. There are no providers associated with them. They use ones of the injector from the element that triggers (directly = a component or indirectly = a component that triggers the call of service chain)
Regarding your other questions:
- @Injectable. To inject into a class, you need a decorator. Components have one (the @Component one) but services are simple classes. If a service requires dependencies to be injected in it, you need this decorator.
- @Inject. In most times, the type of constructor parameters is enough to let Angular2 determines what to inject. In some cases (for example, if you explicitly use an OpaqueToken and not a class to register providers), you need to specify some hints about what to inject. In such cases, you need to use @Inject.
See these questions for additional details: