Javascript Aurelia:基类的部分注入

Javascript Aurelia:基类的部分注入,javascript,inheritance,ecmascript-6,dependency-injection,aurelia,Javascript,Inheritance,Ecmascript 6,Dependency Injection,Aurelia,我没有找到一个处理这个问题的好例子,在继承中,一些构造函数参数应该由子类定义和传递,其余的应该被注入 export class Superclass { static inject = [Service1, Service2]; constructor( //parameter(s) intented to be passed by subclasses parameterFromSubclass, //services inte

我没有找到一个处理这个问题的好例子,在继承中,一些构造函数参数应该由子类定义和传递,其余的应该被注入

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
    }

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

}
为了使其更加复杂,子类可能还需要注入自己的服务

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

}

一个显而易见的解决方案是列出并注入子类上的所有依赖项。但这将要求所有子类也必须维护超类的依赖关系

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;
    }

}
幸运的是,Aurelia DI在定义注入(可以是静态数组或类装饰器)时支持继承,因此基类依赖也“继承”,因此不需要显式指定,并且可以使用扩展运算符传递。这样,子类就得到了注入的所有依赖项

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
    }

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

}

另一种选择是使用工厂,但这不能应用于继承,这意味着必须将基类重构为服务。因此,当使用继承时,我发现上面的解决方案更简单


备注:问题和措辞基本上导致了答案,对此表示抱歉。

另一种选择是在基类中不使用构造函数注入或基于装饰器的注入,而只是在那里手动使用Aurelia的容器实例,以避免继承问题,虽然有一些缺点:*对Container.instance的静态访问将提供根容器,而根容器可能不遵守生命周期设置。注入基类的服务也可能具有依赖关系*通常,构造函数参数更干净,不会将不必要的DI逻辑混合到类中*手动访问增加了复杂性,对于每个参数,必须添加container.get(Foo)