DI poza klasami

Do tej pory jedynymi typami, w których stosowano wstrzykiwanie były klasy, ale Angular nie ogranicza się do tego.

Do tej pory dostawcy byli używani w doniesieniu do @NgModule Angulara. Na liście provider również były tylko identyfikatory klas. Angular pozwala programiście na dokładniejsze określenie dostawców. Odbywa się to za pomocą literału obiektowego ({}):

import { NgModule } from '@angular/core';
import { App } from './containers/app'; // hypothetical app component
import { ChatWidget } from './components/chat-widget';

@NgModule({
  providers: [ { provide: ChatWidget, useClass: ChatWidget } ],
})
export class DiExample {};

Ten przykład jest jeszcze wprowadza tak zwany "długi format" Angulara. Deklaruje się w nim klasę dostarczanego obiektu oraz klasę użytą do jego stworzenia (która może być klasą pochodną w stosunku do tej pierwszej). Na przykład programista może stworzyć MockChatWidget:

import { NgModule } from '@angular/core';
import { App } from './containers/app'; // hypothetical app component
import { ChatWidget } from './components/chat-widget';
import { MockChatWidget } from './components/mock-chat-widget';

@NgModule({
  providers: [ { provide: ChatWidget, useClass: MockChatWidget } ],
})
export class DiExample {};

Tu widać niesamowitą siłę wynikającą z połączenia DI z programwaniem obiektowym. Rozbudowa aplikacji nie wymaga analizy zależności - możemy się skupić na szczegółach implementacyjnych komponentu.

Iniektor może jednak wykorzystywać więcej danych, niż tylko klasy. useValue iuseFactory. Na przykład:

import { NgModule } from '@angular/core';
import { App } from './containers/app'; // hypothetical app component

const randomFactory = () => { return Math.random(); };

@NgModule({
  providers: [ { provide: 'Random', useFactory: randomFactory } ],
})
export class DiExample {};

W hipotetycznym elemencie aplikacji Random może być wstrzykiwany jak:

import { Component, Inject, provide } from '@angular/core';

@Component({
  selector: 'app-root',
  template: `Random: {{ value }}`
})
export class AppCompoennt {
  value: number;

  constructor(@Inject('Random') r) {
    this.value = r;
  }
}

Powyższy przykład wykorzystuje przepis useFactory . Angular spodziewa się w takim przypadku, że podana wartość będzie funkcją (fabryki). Należy zwrócić uwagę na to, że Random jest w cudzysłowie, zarówno w provide jak i konstruktorze.

Jeszcze prostszym jest przepis o nazwie useValue:

import { NgModule } from '@angular/core';
import { AppComponent } from './containers/app.component'; // hypothetical app component

@NgModule({
  providers: [ { provide: 'Random', useValue: Math.random() } ],
})
export class DiExample {};

W tym przypadku wynik Math.random jest przypisany douseValuejako własność przekazana do dostawcy.

Zobacz przykłady:

Random DI 1 [065]
Random DI 2 [066]