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 douseValue
jako własność przekazana do dostawcy
.
Zobacz przykłady:
Random DI 1 [065]
Random DI 2 [066]