angulartypescriptangular-decorator

Is [providers] necessary when doing constructor dependency injection?


Going through this todo tutorial and it has the following:

 import {TodoDataService} from './todo-data.service';

 @Component({
  // ...
   providers: [TodoDataService]
 })

 constructor(private todoDataService: TodoDataService) {
 }

IIUC we have to declare the TodoDataService in the providers array. This seems redundant. Could the Angular DI read the generated metadata for the component and automatically inject the TodoDataService using constructor injection?

Update

Angular has implemented this to some extent now. I asked them to remove providedIn:root as well and they said they have things on the roadmap for that.


Solution

  • From the Angular.io docs:

    Injector bubbling

    When a component requests a dependency, Angular tries to satisfy that dependency with a provider registered in that component's own injector. If the component's injector lacks the provider, it passes the request up to its parent component's injector. If that injector can't satisfy the request, it passes it along to its parent injector. The requests keep bubbling up until Angular finds an injector that can handle the request or runs out of ancestor injectors. If it runs out of ancestors, Angular throws an error.

    My understanding of this is that if your component provides a service, you get one instance of that service per component. If it doesn't, it walks up the component tree until it finds something that does provide it. So something has to provide it.

    I think it actually does check the generated metadata, but it is using it only to see what service the component needs, not where the service comes from (which is what providers:[TodoDataService] is for).

    In my application, most of my services are provided in my app.module.ts, so I get one instance of each service throughout the whole app.