简体   繁体   中英

Dependency injection in abstract class with TypeScript and Angular 5

I've got the BaseComponent which got some dependencies injected. The first dependency EntityService is correct and necessary.

But AnyOtherService is only used inside the abstract BaseComponent . Instead of injecting it inside the ChildComponent , where it is not used, I'd like to inject it only inside BaseComonent .

Why do I have to push it through the ChildComponent towards the BaseComponent ? The best solution would be to encapsulate it inside the BaseComponent .

base.component.ts

export abstract class BaseComponent {
  constructor(
    protected entityService: EntityService,
    // protected anyOtherService: AnyOtherService // @todo add this
  ) {
  }
}

child.component.ts

@Component()
export class ChildComponent extends BaseComponent {

  constructor(
    private firstService: FirstService,
    private secondService: SecondService,
    protected anyOtherService: AnyOtherService // @todo remove this
  ) {
    super(
      firstService,
      anyOtherService // @todo remove this
    ); 
  }
}

So you can pass Injector to base component constructor( UPDATE ):

export abstract class BaseComponent {
  protected anyOtherService: AnyOtherService;

  constructor(
    inject: Injector
    protected entityService: EntityService,
    // protected anyOtherService: AnyOtherService // @todo add this
  ) { 
     this.anyOtherService= inject.get(AnyOtherService);
  }
}


@Component()
  export class ChildComponent extends BaseComponent {

  constructor(
    inject: Injector,
    private firstService: FirstService,
    private secondService: SecondService       
  ) {
    super(
     inject,
     firstService
    );       
  }
}

The idea is to inject Injector and some providers in child component and pass it to parent base component without passing all base class dependencies. With passing injector, child classes(components) doesn't need to inject all dependencies of parent(base) class and pass throw super(dep1, dep2..., baseDep1... ).

Could you please explain in your answer, why it has to be like you've said with private inside child and protected inside parent?

I think the injector shouldn't be the property of child/base class. If will be, the error throws as you comment below. The error is about, Base and Child class can't have the same property in their class. That's why we need to omit private/protected or any access modifier to injector in constructor, also because Injector is only needed in constructor to manually inject what we need in some specific cases as this.

you can try like this , make use of injector , export it from appmodule and use it in you base class

import {Injector} from '@angular/core';

//exporting injector 
export let AppInjector: Injector;

export class AppModule {
  constructor(private injector: Injector) {
    AppInjector = this.injector;
  }
}

and then base.component.ts

export abstract class BaseComponent {
  private anyOtherService : AnyOtherService ;
  constructor(
    protected entityService: EntityService,
    // protected anyOtherService: AnyOtherService // @todo add this
  ) {
    this.anyOtherService = AppInjector.get(AnyOtherService );
  }
}

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