Angular inject service into base class but not in sub-class and use the parent service in sub-classes

Viewed 2912

Using Angular 7 & Typescript: I have a base class that uses a lot of services and child classes (about 40 sub-class) and I don't want to add those services in all subclass constructor and pass them to super() but I still need to use those services in all subclass.


export class parentTool {

    constructor(type: string, public service1: Service1, public service2: Service2,public service3: Service3, public service4: Service4){}
}

export class ChildTool1 extends parentTool {

    constructor(public service1: Service1, public service2: Service2,public service3: Service3, public service4: Service4) {

        super("tool1", service1, service2, service3, service4);
    }
}

export class ChildTool2 extends parentTool {

    constructor(public service1: Service1, public service2: Service2,public service3: Service3, public service4: Service4) {

        super("tool2", service1, service2, service3, service4);
    }
}
3 Answers

I use to have the same problem so I end up doing manulay DI (dependency injection) by using injector service

this static class use to store a refrence of injector service

export class AppInjector {

  private static injector: Injector;

  static setInjector(injector: Injector) {
    AppInjector.injector = injector;
  }

  static getInjector(): Injector {
    return AppInjector.injector;
  }
}   

at app module I set the injoctor service

export class AppModule { 
  constructor(injector:Injector){
      AppInjector.setInjector(injector);// save a injector ref 
  }
}

you need to store the service before you start do any DI (dependency injection)

in the base component

export class BaseComponent {
  protected utilitiesService: UtilitiesService; //  service
  protected loggingService: LoggingService; //  service

  constructor() {

      const injector = AppInjector.getInjector();

      this.utilitiesService = injector.get(UtilitiesService); //  DI
      this.loggingService = injector.get(LoggingService); //  DI


  }

}

child class now have access to all service injected by the injector class

    export class ChildComponent extends BaseComponent {
      constructor() {
        super();
      }
    }

demo

Add one more service and inject all required services in there. We can simply add that service in a sub class and pass it to parent in super.

@injectable()
export class ParentService {
    constructor(type: string, private service1: Service1, private service2: Service2,private service3: Service3, private service4: Service4){}
    executeService1(){
        this.service1.method1();
    }
}

export class parentTool {
    constructor(private parentService: ParentService){}
}

export class ChildTool1 extends parentTool {
    constructor(public parentService: ParentService) {
        super("tool1", parentService);
    }
}

export class ChildTool2 extends parentTool {
    constructor(public parentService: ParentService) {
        super("tool2", parentService);
    }
}

You can use a global injector for preventing injecting all services in all child classes. In your case, it will be something like this:

import {Injector} from '@angular/core';
//other imports
export class parentTool {
  public service1: Service1
  public service2: Service2
  public service3: Service3
  public service4: Service4
      constructor(type: string,injector: Injector){
        this.serviceInject1 = injector.get(Service1);
        this.serviceInject2 = injector.get(Service2);
        this.serviceInject3 = injector.get(Service3);
        this.serviceInject4 = injector.get(Service4);
      }
  }

  export class ChildTool1 extends parentTool {

      constructor(injector: Injector) {  
          super(injector);
          this.service1.someMethodCall()
      }
  }

  export class ChildTool2 extends parentTool {

      constructor(injector: Injector) {  
          super(injector);
          this.service1.someMethodCall()
      }
  }
Related