[英]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.