I'm about to use a multi-provider to export the dependencies of my dependency along with itself, so they could be injected into a component at once.
For a component
import {Component} from 'angular2/core';
import { FOO_PROVIDERS } from './foo';
@Component({
selector: 'app',
providers: [FOO_PROVIDERS]
})
export class App {}
the following
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
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 would expect them to do the similar job.
Is there a proper use for multi-provider in this case?
When you register provide(Foo, ...),
than you can
constructor(foo:Foo)
with multi: true
you get passed 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 would get passed to foo
an array containing an instance of Foo
and a as 2nd item a list of providers (these contained in HTTP_PROVIDERS
)
update
Maybe you have different expectations of what should happen. I don't see how @Inject(Http) http
is related here. HTTP_PROVIDERS
is only registered as value for Foo
. What value you pass to useValue
is irrelevant when providers are resolved. DI looks up providers for Foo
and passed the assigned value and doesn't care at all what that value is. There is no provider for Http
in your example therefore Foo
itself couldn't get Http
injected. You would need to register Http
, which is done when 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]);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With