[英]Get injector from module in angular 8
問題:
我正在為angular的非路由模塊設置延遲加載。 在版本7中,我使用了NgModuleFactoryLoader
並將其功能load
到延遲加載模塊並獲取該模塊的第一個入口點(服務在外情況下)
this.loader.load('path-to-module')
.then(factory => {
const module = factory.create(this._injector);
return module.injector.get(EntryService);
});
但是在Angular 8中, NgModuleFactoryLoader
被棄用了,所以我不得不以這種方式加載模塊:
import('path-to-module')
.then(m => m.MyModule)
.then(myModule => {
...
});
這里的問題是我無法在新的延遲加載中檢索工廠並在此處獲取提供者(IVY的想法之一-沒有工廠)。
我已經嘗試過的:
第一個解決方案(僅適用於不適合我們的JIT編譯器,因為我將AOT編譯器用於產品)
import('path-to-module')
.then(m => m.MyModule)
.then(myModule => {
return this._compiler.compileModuleAsync(myModule)
.then(factory => {
const module = factory.create(this._injector);
return module.injector.get(EntryService);
});
});
第二種解決方案(臟且未完全檢查。它使用的是ngInjectorDef
,這是IVY的新功能,尚無任何描述的API):
import('path-to-module')
.then(m => m.MyModule)
.then(myModule => {
const providers = myModule['ngInjectorDef'].providers; // Array<Providers>
... find EntryService in providers
});
ngInjectorDef
是一個靜態模塊類屬性,該屬性是由angular添加的,並且具有工廠,提供者和進口的屬性。
資料來源:
No NgFactory file anymore
) 我不會說訪問ngInjectorDef
屬性是“骯臟的黑客”。 是的,它沒有在任何地方進行文檔記錄,因為正如Igor Minar所說,Ivy是Angular 8的選擇性加入預覽。但是Viktor Savkin的某些文章中已經提到了很多私有函數,例如directiveInject
。
您不應在providers
屬性中搜索服務。 想象一下,有20多個提供者, EntryService
名稱在生產中將EntryService
t
或k
。
如果使用Ivy-有一個名為createInjector
的私有函數,該函數接受模塊構造函數作為參數。
@Injectable()
export class EntryService {
public logFromEntryService(): void {
console.log('Logging from EntryService...');
}
}
@NgModule({
providers: [EntryService]
})
export class EntryModule {
public static getEntryService: () => EntryService = null;
constructor(injector: Injector) {
EntryModule.getEntryService = () => injector.get(EntryService);
}
}
假設您有這樣的代碼,讓我們使用動態導入來加載此EntryModule
:
import { ɵcreateInjector as createInjector } from '@angular/core';
export class AppComponent {
constructor(private injector: Injector) {
this.loadEntryModule();
}
private async loadEntryModule(): Promise<void> {
const { EntryModule } = await import('./entry.module');
createInjector(EntryModule, this.injector);
EntryModule.getEntryService().logFromEntryService();
}
}
createInjector
用於實例化EntryModule
,instanting之后-該getEntryService
靜態方法並不等於null
。
我們還可以公開injector
屬性,例如:
public static injector: Injector = null;
constructor(injector: Injector) {
EntryModule.injector = injector;
}
可以將其視為服務定位器,這是一種反模式。 但是取決於你!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.