我正在为调试目的创建一个@Log()
装饰器函数;
我希望Decorator将其中的一些逻辑委托给LoggingService
,而{{1}}依赖于应用程序中的其他服务......
我一直在尝试很多不同的东西,最简单/最直接的方法是将主(或共享)模块的Injector缓存为模块本身的静态道具(参见下面链接的StackBlitz示例),对于延迟加载的模块,但不适用于急切加载的模块...
非工作poc:https://stackblitz.com/edit/angular-j1bpvx?file=app%2Fdecorator.ts
有没有办法可以在那里使用那个服务?
谢谢!
答案 0 :(得分:6)
类装饰器在类定义上执行一次。为了在调用AppModule.injector.get(LoggingService)
时避免竞争条件,应将其移动到已定义AppModule.injector
的位置,即类方法。
constructor.prototype[hook] = function (args) {
const loggingService = AppModule.injector.get(LoggingService);
loggingService.log({ ... })
...
这也会与AppModule
产生紧密耦合,并阻止单元重复使用或单独测试。建议使用另一个对象来保存injector
属性,例如分配injector
不在主要但在导入到AppModule
的子模块中:
export class InjectorContainerModule {
static injector: Injector;
constructor(injector: Injector) {
InjectorContainerModule.injector = injector;
}
}
答案 1 :(得分:2)
这将打印
LoggingService:HelloComponent - 调用了ngOnInit
轻微更改 - 基本上使用angular Injector#example
中的ReflectiveInjector
import { ReflectiveInjector } from '@angular/core';
const injector = ReflectiveInjector.resolveAndCreate([
{provide: 'loggingService', useClass: LoggingService}
]);
const loggingService = injector.get('loggingService');
我确信您可以在应用模块中使用useExisting
并使用LoggingService
作为提供商。