I use Angular2 DI to inject a Logger
class in various services and components. Is it possible to create and inject a new object every time a Logger
is requested? I tried the FactoryProvider
; it instantiates a single instance once and then injects the same instance everywhere.
Registering a separate Logger
provider for every component would solve this but that seems to be an overkill.
So far I found no better solution but it would make things much more convenient for me.
EXAMPLES
This is my super-convenient goal:
// 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"!!!
}
}
This could be done now, however, it needs a little more boilerplate:
// 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"
}
}
MORE UPDATE
Well, I was digging in Angular2 issue tracker and found this guy (#18015) where they argue about a DI extension solving this problem and the way it would affect the whole DI mechanism. It seems that this would be the real solution but there is no conclusion yet. (@bryan60 seems to be right: currently -- 5.0.0-rc.1 -- this is NOT supported.)