【发布时间】:2018-03-16 08:12:07
【问题描述】:
我使用 Angular2 DI 在各种服务和组件中注入 Logger 类。每次请求Logger 时是否可以创建和注入一个新对象?我试过FactoryProvider;它实例化一个实例一次,然后在各处注入相同的实例。
为每个组件注册一个单独的Logger 提供程序可以解决这个问题,但这似乎有点过头了。
到目前为止,我没有找到更好的解决方案,但它会让我更方便。
示例
这是我超级方便的目标:
// logger.service.ts
export class Logger {
static LoggerProvider: FactoryProvider = {
provide: Logger,
useFactory: () => {
return new Logger();
},
/* Actually we need a LoggerService here, I omitted that. */
};
name: string;
info(msg: string) { console.log('INFO', this.name, msg); }
}
// status.service.ts
@Injectable()
export class StatusService {
constructor(private log: Logger) {
this.log.name = 'StatusService';
this.log.info('ctor'); // logs "INFO StatusService ctor"
}
test() {
this.log.info('test'); // should log "INFO StatusService test"
}
}
// home.component.ts
@Component({ /* ... */})
export class HomeComponent {
constructor(
private statusService: StatusService
private log: Logger,
) {
// Got the same logger as the StatusService!!!
this.log.name = 'HomeComponent';
this.log.info('ctor'); // logs "INFO HomeComponent ctor"
this.statusService.test(); // breaks and logs "INFO HomeComponent test"!!!
}
}
这可以现在完成,但是,它需要更多样板:
// status.service.ts
@Injectable()
export class StatusService {
private log: Logger;
constructor(loggerService: LoggerService) {
this.log = loggerService.createLogger('StatusService');
this.log.info('ctor'); // logs "INFO StatusService ctor"
}
test() {
this.log.info('test'); // definitely logs "INFO StatusService test"
}
}
更多更新
好吧,我在 Angular2 问题跟踪器中进行挖掘,发现 this guy (#18015) 在那里他们争论解决这个问题的 DI 扩展以及它会影响整个 DI 机制的方式。似乎这将是真正的解决方案,但还没有结论。 (@bryan60 似乎是对的:目前 -- 5.0.0-rc.1 -- 不支持。)
【问题讨论】:
-
请展示各种服务和组件中的Logger类的实际代码。
-
我相信您所描述的正是单独的
provider的用途。虽然在应用程序级别拥有一个提供程序会创建一个Logger实例,用于注入Logger的任何位置,但使用每个组件的提供程序同样会创建一个Logger每个组件的实例 -
你想要的是每次注入一个新的记录器,通过 DI 做到这一点的唯一方法是在注入的任何地方提供它。这是 DI 的预期行为。您应该审查您的设计决策,以确定您真正需要它的原因,并看看您是否不能想出更好的东西。
-
看看这是否有帮助:stackoverflow.com/a/38473200/2015408
标签: angular typescript dependency-injection