How to use Dependency Injection (DI) correctly in Angular2?

George Huang picture George Huang · Mar 20, 2016 · Viewed 19.1k times · Source

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 :-)

Answer

Ankit Singh picture Ankit Singh · Mar 20, 2016

Broad question, TL;DR version


@Injectable()

  • is a decorator which tells the typescript that decorated class has dependencies and does not mean that this class can be injected in some other.

  • And then TypeScript understands that it needs to Inject the required metadata into decorated class when constructing, by using the imported dependencies.

bootstrap(app, [service])

  • bootstrap() takes care of creating a root injector for our application when it’s bootstrapped. It takes a list of providers as second argument which will be passed straight to the injector when it is created.

  • You bootstrap your application with the services that are gonna be used in many places like Http, which also means you'll not need to write providers: [Http] in your class configuration.

providers: [service]

  • providers also does the work of passing all the services' arguments to Injector .

  • You put services in providers if it's not bootstrap()ped with. And is needed only in a few places.

@Inject()

  • is also a decorator a function that does the work of actually injecting those services
    like this. constructor(@Inject(NameService) nameService)
  • but if you use TS all you need to do is this constructor(nameService: NameService) and typescript will handle the rest.

Further Reading

Hope this helps. :)