javascript - Förstå beroendeinjektion i angular2


Här är ett kodsnutt

@Component({
     ... : ...
     providers: [MyService]
})
export class MyComponent{

     constructor(private _myService : MyService){
     }

     someFunction(){
          this._myService.getSomething();
     }
}

Och här är min förståelse/fråga om hur det fungerar i Angular2/TypeScript.

  • Ett singleton-objekt kommer att skapas varje gång vi skriver MyService i providers.
  • Varför ska man ge det i en konstruktor? Kan vi göra det någon annanstans?
  • vem som än anropar konstruktören (javascript-motorn kanske), hur skulle den veta vad som ska skickas in till argumenten
  • eller har jag fel, är det inte ens ett argument?

REDIGERA

  • vad händer om jag anger providers: [MyService] på två kontroller? Kommer det att skapa en ny instans eller hämta från en?

Svar #1

  • provider: [ ... ] anger räckvidden för den enskilda instans som upprätthålls för varje leverantör. Räckvidden är den komponent där typen läggs till i providers: [ ... ] och dess efterföljare (så länge de inte åsidosätter den med en annan leverantör med samma nyckel). Att lista en leverantör i bootstrap(AppComponent, [SomeProvider]) gör den globalt tillgänglig, igen så länge den inte skuggas av en leverantör på en komponent.

  • Angular2 stöder endast konstruktörinjektioner. Det finns andra strategier men de anses problematiska.

  • Angular analyserar konstruktorns parameter för att veta vilka parametrar som behöver skickas in när en instans skapas, hämtar lämpliga instanser från dess leverantörer eller föräldraleverantörer och skickar in dem.
    För att detta ska fungera måste klasser dekoreras med @Injectable() om de inte är komponenter, direktiv eller pipor.

  • DI (Dependency injection) skickar endast instanser till konstruktörsparametrar för instanser som den själv har skapat. För varje instans den skapar, kontrollerar den konstruktörsparametrarna och hämtar de matchande instanserna från sig själv (providers) och skickar in dem. Om en av dessa beroenden i sin tur själv behöver konstruktörsparametrar, sker detta rekursivt tills alla beroenden är lösta.
    Jasmine skickar inte instanser till konstruktören själv, det måste istället delegera detta till DI.

Uppdatering till din "Redigera"

Om samma tjänst läggs till på olika ställen bootstrap(...), providers: [...] så upprätthålls en enda instans per varje leverantör.

När en klass begär ett beroende (genom en konstruktörsparameter) tittar DI uppåt mot bootstrap() och returnerar instansen av den första leverantören den hittar. (detta är anledningen till att leverantörer på komponenter skuggar leverantörer på förfäderkomponenter eller bootstrap(...))

Kort: ja, två leverantörer av samma tjänst resulterar i två olika instanser.

Relaterade artiklar