I am trying to write a simple LoggerService
for angular 2. On calling logger.log('msg')
method of this service, the logger should automatically prefix the caller class identifier. So, if a call like logger.log('hello')
is made from MyComponent
, the output should be MyComponent: hello
.
To do so, I have created a providerFactory and Service as below:
export function provideLogger(sourceClass: string) {
return {
provide: LoggerService,
useFactory: (config: LogConfig) => new LoggerService(sourceClass, config),
deps: ['LogConfig'] //LogConfig is a simple JS object common for application
};
}
@Injectable()
export class LoggerService {
constructor(private sourceClass:string, private config: LogConfig) { }
log(message: string) {
console.log(`${this.sourceClass}: ${message}`);
}
}
This works fine when using with a component, used like below:
@Component({
templateUrl: 'myComponent.html',
providers: [provideLogger('MyComponent')]
})
export class MyComponent {
constructor(private logger: LoggerService){
logger.log('Hello'); //outputs: MyComponent: Hello
}
}
The problem I am facing here is: I am not able to inject a new instance of this LoggerService
in any other Service (below is sample ApiService). As I understands it, Injectors are not available at Service level for injecting other service.
@Injectable() //can't mentioned providerFunction
export class ApiService {
constructor(private logger: LoggerService) {
logger.log('hello api'); //should output ApiService: hello api
}
}
How can I achieve to inject a new instance of LoggerSerivce in another @Injectable
Service? Thanks!
You can't creat new instance of service!
service is "singleton" class..(constructor called only once!).
you should get the class name as a parameter in the "log" function .
log(sourceClass:string, message: string) {
console.log(`${sourceClass}: ${message}`);
}
logger.log('MyComponent', 'Hello'); //outputs: MyComponent: Hello
or: use normal class instead of service. for example:
@Injectable()
export class ApiService {
private logger: LoggerService;
constructor( private config: LogConfig) {
this.logger = new LoggerService("ApiService", config)
this.logger.log('hello api');
}
}
@Component({
templateUrl: 'myComponent.html'
})
export class MyComponent {
private logger: LoggerService;
constructor(private config: LogConfig){
this.logger = new LoggerService("MyComponent", config)
this.logger.log('Hello'); //outputs: MyComponent: Hello
}
}
you are anyway try to creating multiple instances of the service.
Good Luck!!!
What i would do is to have generic log function:
public log(prefix: string, message: string);
And also another function, that would curry the parameter for me:
public getLogger<T>(prefix: string) {
return (message: string) => this.log(prefix, message);
}
I then could use it like this:
private LOGGER = this.loggerService.getLogger('MyService');
fun doSomething() {
this.LOGGER('My important message');
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.