简体   繁体   中英

Inject new Instance of Service in another Service in Angular 2

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM