Inject provider into another provider

You have two options:

  1. As mentioned in the other answer, you have to put your services in your component's providers array, like you did:

    providers: [P1, P2]
    

    And in P1's constructor just inject it:

    export class P1 {
        constructor(private p2: P2){}
    }
    
  2. If you don't want to put it in the providers array, you can do it in the bootstrap method that bootstraps your main component:

    bootstrap(AppComponent, [P2]);
    

And again, just inject it the same way in P1

I don't recommend the second one, and the creators of Angular 2 aren't recommending it either. If you want a global service available everywhere (in other services and components, just put it in the providers array of the root component)

Source: https://angular.io/docs/ts/latest/guide/dependency-injection.html

We do have to configure the injector by registering the providers that create the services we need in our application. We'll explain what providers are later in this chapter. Before we do, let's see an example of provider registration during bootstrapping:

// Injecting services in bootstrap works but is discouraged

bootstrap(AppComponent, [HeroService]);

The injector now knows about our HeroService. An instance of our HeroService will be available for injection across our entire application.

Of course we can't help wondering about that comment telling us not to do it this way. It will work. It's just not a best practice. The bootstrap provider option is intended for configuring and overriding Angular's own pre-registered services.

The preferred approach is to register application providers in application components. Because the HeroService will be used within the Heroes feature area — and nowhere else — the ideal place to register it is in the top-level HeroesComponent.


Injectables support dependency Injection in the same way that components do, through constructor injection.

@Injectable()
export class P1 {
    constructor(private p2: P2){}
}

You can declare it as a provider available to the entire application by adding it to the bootstrap

bootstrap(MyAppComponent, [P1, P2, ...]);

In fact, injectors can be only configured at the component level or when bootstrapping the application.

When you set providers at the component level, every classes involved in the processing will have a access to these providers: sub components, services. But you can't configure providers for services themselves.

If you configure providers at the bootstrap level (when calling the bootstrap function), all elements in the application will be able to use these providers.

In fact, dependency injector of Angular2 leverages hierarchical injectors. This means that if the provider isn't found at a level, it will be look for in the level above and so on.

Here is an overview of all these elements and there relations:

Application
(providers defined in bootstrap)
     |
AppComponent
(providers defined in the providers attribute)
     |
ChildComponent
(providers defined in the providers attribute)
  getData()     --- Service1 --- Service2

To be able to use Service2 in Service1, the corresponding provider must be found in the providers tree.

In such application, we have three injectors:

  • The application injector that can be configured using the second parameter of the bootstrap function
  • The AppComponent injector that can be configured using the providers attribute of this component. It can "see" elements defined in the application injector. This means if a provider isn't found in this provider, it will be automatically look for into this parent injector. If not found in the latter, a "provider not found" error will be thrown.
  • The ChildComponent injector that will follow the same rules than the AppComponent one. To inject elements involved in the injection chain executed forr the component, providers will be looked for first in this injector, then in the AppComponent one and finally in the application one.

This answer could give you more details about the hierarchical injectors:

  • What's the best way to inject one service into another in angular 2 (Beta)?

Tags:

Angular