的噴射器是與供應商/服務的容器。它實現了一個方法get
並返回服務的一個實例。讓我們實現JS僞噴油器的最基本的版本:
class ReflectiveInjector {
providers = [];
static resolveAndCreate(providers) {
providers.forEach((provider)=>{
providers.push({token: provider.provide, instance: new provider.useClass})
});
)}
get(dep) {
return providers.find((provider)=>{ return provider.token === token });
}
}
現在,我們需要創建注入的情況下才可以使用它。當我們創建它時,我們定義提供者:
const existingInjector = ReflectiveInjector.resolveAndCreate([{provide: A, useClass: A }]);
const AInstance = existingInjector.get(A);
因此,您看到要使用注射器,必須先創建注射器。它沒有任何特定的方法允許在創建完成後添加提供程序,因此我們無法添加任何新的提供程序。
您注入組件構造函數的注入器已由Angular創建。您無法添加任何內容,只能查詢已定義的提供者。如果您需要提供B
課程,則不能使用現有注射器來完成。你需要一個新的。這就是ReflectiveInjector
類的用途。它允許您通過創建注入器的新實例並註冊新的提供者來添加新的提供者。最好的部分是它也可以設置一個噴油器鏈。
讓我們有點修改resolveAndCreate
和get
方法來允許鏈接注射器:
class ReflectiveInjector {
providers = [];
parent;
static resolveAndCreate(providers, parent) {
this.parent = parent;
...
}
get(dep) {
let found = providers.find((provider)=>{ return provider.token === token });
if (!found && parent) {
found = parent.get(dep);
}
return found;
}
所以現在只有左邊是使用它:
// passing existingInjector as a parent
const childInjector = ReflectiveInjector.resolveAndCreate([{provide: B, useClass: B }], i);
const AInstance = childInjector.get(A);
const BInstance = childInjector.get(B);
現在,假如有人可能希望得到訪問我們的existingInjector
。我們需要一個令牌來獲得這個現有的注射器。讓我們來定義此令牌是這樣的:
abstract class Injector {}
,讓我們寫一個函數,將讓現有的注射器:
function resolveDependency(token) {
if (token === Injector) {
return existingInjector;
}
}
當執行元件的構造,現在假設角,使用令牌你指定獲取依賴關係並將它們傳遞給resolveDependency
函數。所以,你這樣寫:
// the Injector here is a reference to our abstract Injector class and simply used as a token
MyComp {
constructor(private injector: Injector) { ... }
}
這裏的令牌是Injector
這是我說的是傳遞到resolveDependency
功能並返回現有的注射器。
'Injector'是一個容器,不能創建新的供應商。 'ReflectiveInjector'具有工廠方法,允許您在運行時定義新的提供者(即創建新的子注入器)。 – cgTag
@ThinkingMedia兒童注射器意味着孩子的依賴? – JEMI
@ThinkingMedia我有一個沒有孩子依賴的服務。我想明確地創建它的一個實例。哪一個是推薦的方法? – JEMI