Angular 2 multi-provider for exporting dependency dependencies

I am going to use multi-provider to export the dependencies of my dependency together with myself so that they can be injected into the component right away.

For component

import {Component} from 'angular2/core'; import { FOO_PROVIDERS } from './foo'; @Component({ selector: 'app', providers: [FOO_PROVIDERS] }) export class App {} 

below

 import {Inject, Injectable, provide} from 'angular2/core'; import {Http, HTTP_PROVIDERS} from 'angular2/http'; export class Foo { constructor(@Inject(Http) http) {} } export const FOO_PROVIDERS = [ provide(Foo, { useClass: Foo, multi: true }), provide(Foo, { useValue: HTTP_PROVIDERS, multi: true }) ]; 

will result in

There is no provider for Http! (App → Foo → Http)

And this

 import {Inject, provide} from 'angular2/core'; import {Http, HTTP_PROVIDERS} from 'angular2/http'; class Foo { constructor(@Inject(Http) http) {} } export const FOO_PROVIDERS = [Foo, HTTP_PROVIDERS]; 

will work fine while I expect them to do a similar job.

In this case, the correct use for multiple providers?

+6
source share
1 answer

When you register provide(Foo, ...), , than you can

 constructor(foo:Foo) 

with multi: true you will get all providers registered as Foo

 constructor(foo:any) 

WITH

 export const FOO_PROVIDERS = [ provide(Foo, { useClass: Foo, multi: true }), provide(Foo, { useValue: HTTP_PROVIDERS, multi: true }) ]; 

and

 constructor(@Inject(Foo) foo:Foo[]) 

you will receive an array passed to Foo containing an instance of Foo , and as a second element, a list of providers (they are contained in HTTP_PROVIDERS )

Update

You may have different expectations about what should happen. I do not see here as @Inject(Http) http . HTTP_PROVIDERS is only registered as a value for Foo . What value you switch to useValue does not matter when the providers are allowed. DI looked for suppliers for Foo and passed the assigned value, and no matter what that value is. In your example, there is no Http provider, so Foo itself could not get Http . You will need to register Http , which will be done if you add HTTP_PROVIDERS directly to providers (not in useValue ), because HTTP_PROVIDERS contains Http (which is equivalent to provide(Http, {useClass: Http})

Update2

 // An injected service that itself needs to get passed in a dependency @Injectable() class Foo { constructor(private http:Http); } // container for a bunch of dependencies @Injectable() class MyProviders { // add everything you want to make available in your components constructor(public foo:Foo, public bar:Bar, ...); } class MyComponent { // inject just MyProviders and use the dependencies it provides constructor(private providers: MyProviders) { // access provided values providers.foo.doSomething(); providers.bar.doSomethingElse(); } } // Add all providers to allow DI to resolve all above dependencies bootstrap(AppComponent, [HTTP_PROVIDERS, Foo, Bar]); 

}

+3
source

All Articles