javascript - Angular 2 multi-provider pentru exportarea dependențelor unei dependențe


Sunt pe cale să folosesc un multi-provider pentru a exporta dependențele dependenței mele împreună cu ea însăși, astfel încât să poată fi injectate într-un component dintr-o dată.

Pentru un component

import {Component} from 'angular2/core';
import { FOO_PROVIDERS } from './foo';

@Component({
  selector: 'app',
  providers: [FOO_PROVIDERS]
})
export class App {}

următorul

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 })
];

va rezulta în

Nu există furnizor pentru Http! (App -> Foo -> Http)

Și asta

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];

va funcționa bine, în timp ce m-aș aștepta ca ei să facă un job similar.

Există o utilizare corespunzătoare pentru multi-provider în acest caz?

Răspuns #1

Când înregistrezi provide(Foo, ...), atunci poți

constructor(foo:Foo)

cu multi: true primești toți furnizorii înregistrați ca Foo

constructor(foo:any)

Cu

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

și

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

vei primi în foo un array conținând o instanță de Foo și ca al 2-lea element o listă de furnizori (acestea fiind conținute în HTTP_PROVIDERS)

actualizare

Poate ai așteptări diferite despre ceea ce ar trebui să se întâmple. Nu văd cum @Inject(Http) http este relevant aici. HTTP_PROVIDERS este înregistrat doar ca valoare pentru Foo. Ce valoare treci la useValue este irelevant atunci când se rezolvă providerii. DI caută providerii pentru Foo și transmite valoarea atribuită și nu-i pasă deloc ce valoare este aceasta. Nu există un provider pentru Http în exemplul tău, prin urmare Foo în sine nu ar putea să primească Http injectat. Ar trebui să înregistrezi Http, ceea ce se face atunci când adaugi direct HTTP_PROVIDERS la providers (nu în useValue) pentru că HTTP_PROVIDERS conține Http (ceea ce este echivalent cu provide(Http, {useClass: Http})).

actualizare2

// 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]);

}