Warm tip: This article is reproduced from stackoverflow.com, please click
aurelia dependency-injection ecmascript-6 inheritance javascript

Aurelia: partial injection for base class

发布于 2020-05-25 15:09:26

I didn't find a good example how to deal with the issue, when in inheritance, some constructor parameters should be defined and passed by subclass(es), and rest should be injected.

export class Superclass {
    static inject = [Service1, Service2];
    constructor(
        //parameter(s) intented to be passed by subclasses
        parameterFromSubclass,

        //services intented to be injected
        service1, service2) {
        this.service1 = service1;
        this.service2 = service2;

        //do stuff based on  parameterFromSubclass
    }

}

To make it more complex, subclasses might also need to inject their own services.

export class Subclass extends Superclass {
    static inject = [Service3];
    constructor(service3) {
        const param = 'parameter from subclass'; //could be anything
        super(param, ...?);
        this.service3 = service3;
    }

}
Questioner
balazska
Viewed
13
balazska 2020-03-09 19:34

One obvious solution would be to list+inject all dependencies on the subclass. But this would require that all subclasses has to maintain also the dependencies of the superclass.

export class Subclass extends Superclass {
    static inject = [Service1, Service2, Service3];
    constructor(service1, service2, service3) {
        const param = 'parameter from subclass';
        super(param, service1, service2);
        this.service3 = service3;
    }

}

Luckily, Aurelia DI supports inheritance when defining injects (be that either as a static array or class decorator), so that base class dependencies are also "inherited", so does not need to be specified explicitly and can be passed using spread operator. This way, subclass gets all the dependencies injected.

export class Subclass extends Superclass {
    static inject = [Service1];
    constructor(service1, ...rest) {
        const param = 'parameter from subclass';
        super(param, ...rest);
        this.service3 = service3;
    }

}

One other alternative would be using Factory, but that cannot be applied to inheritance and would mean having to refactor base class into a service. So when using inheritance, I found the solution above simpler.

Remark: the question and the wording is pretty much leading to the answer, sorry about that.