依賴注入(DI)系統仰賴一個執行階段上下文,在這個上下文中,目前的注入器可供使用。
這表示注入器只有在你於這個上下文中執行程式碼時才會運作。
在以下情境中,你會有可用的注入上下文:
- 在由 DI 系統實例化的類別(例如
@Injectable或@Component)建構期間(透過constructor)。 - 在這類類別的欄位初始化器中。
- 在為
Provider或@Injectable的useFactory指定的工廠函式中。 - 在為
InjectionToken指定的factory函式中。 - 在於注入上下文中執行的堆疊框架內。
知道自己何時處於注入上下文中,你就能使用 inject 函式來取得依賴。
NOTE: 關於在類別建構子和欄位初始化器中使用 inject() 的基本範例,請參閱總覽指南。
上下文中的堆疊框架
有些 API 被設計成在注入上下文中執行。例如路由守衛就是如此。這讓你可以在守衛函式中使用 inject 來存取服務。
以下是一個 CanActivateFn 的範例:
const canActivateTeam: CanActivateFn = (
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot,
) => {
return inject(PermissionsService).canActivate(inject(UserToken), route.params.id);
};
在注入上下文中執行
如果你需要在注入上下文中執行某個函式,但自己目前並不在這樣的上下文中,可以使用 runInInjectionContext。
這需要能存取一個注入器,例如 EnvironmentInjector:
hero.service.ts
@Service()
export class HeroService {
private environmentInjector = inject(EnvironmentInjector);
someMethod() {
runInInjectionContext(this.environmentInjector, () => {
inject(SomeService); // Do what you need with the injected service
});
}
}
請注意,只有當注入器能解析所請求的 token 時,inject 才會傳回實例。
斷言上下文
Angular 提供 assertInInjectionContext 輔助函式,用來驗證目前的上下文是注入上下文,若不是則擲出清楚的錯誤。傳入呼叫端函式的參考,讓錯誤訊息指向正確的 API 入口點。這會產生比預設的通用注入錯誤更清楚、更可操作的訊息。
import {ElementRef, assertInInjectionContext, inject} from '@angular/core';
export function injectNativeElement<T extends Element>(): T {
assertInInjectionContext(injectNativeElement);
return inject(ElementRef).nativeElement;
}
接著你可以從注入上下文中(建構子、欄位初始化器、提供者工廠,或透過 runInInjectionContext 執行的程式碼)呼叫這個輔助函式:
import {Component, inject} from '@angular/core';
import {injectNativeElement} from './dom-helpers';
@Component({/* … */})
export class PreviewCard {
readonly hostEl = injectNativeElement<HTMLElement>(); // Field initializer runs in an injection context.
onAction() {
const anotherRef = injectNativeElement<HTMLElement>(); // Fails: runs outside an injection context.
}
}
在上下文之外使用 DI
如果你在注入上下文之外呼叫 inject 或 assertInInjectionContext,Angular 會擲出錯誤 NG0203。