Inheritance and dependency injection

maxhb picture maxhb · Aug 19, 2016 · Viewed 37.5k times · Source

I have a set of angular2 components that should all get some service injected. My first thought was that it would be best to create a super class and inject the service there. Any of my components would then extend that superclass but this approach does not work.

Simplified example:

export class AbstractComponent {
  constructor(private myservice: MyService) {
    // Inject the service I need for all components
  }
}

export MyComponent extends AbstractComponent {
  constructor(private anotherService: AnotherService) {
    super(); // This gives an error as super constructor needs an argument
  }
}

I could solve this by injecting MyService within each and every component and use that argument for the super() call but that's definetly some kind of absurd.

How to organize my components correctly so that they inherit a service from the super class?

Answer

Günter Zöchbauer picture Günter Zöchbauer · Aug 19, 2016

I could solve this by injecting MyService within each and every component and use that argument for the super() call but that's definetly some kind of absurd.

It's not absurd. This is how constructors and constructor injection works.

Every injectable class has to declare the dependencies as constructor parameters and if the superclass also has dependencies these need to be listed in the subclass' constructor as well and passed along to the superclass with the super(dep1, dep2) call.

Passing around an injector and acquiring dependencies imperatively has serious disadvantages.

It hides dependencies which makes code harder to read.
It violates expectations of one familiar with how Angular2 DI works.
It breaks offline compilation that generates static code to replace declarative and imperative DI to improve performance and reduce code size.