我没有找到一个很好的示例来处理该问题,在继承时,应该定义一些构造函数参数,并由子类传递这些参数,并注入其余部分。
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 = [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 Subclass extends Superclass {
static inject = [Service1];
constructor(service1, ...rest) {
const param = 'parameter from subclass';
super(param, ...rest);
this.service3 = service3;
}
}
另一种选择是使用Factory,但是不能应用于继承,这意味着必须将基类重构为服务。因此,在使用继承时,我发现上述解决方案更为简单。
备注:问题和措辞几乎可以得出答案,对此感到抱歉。
另一种选择是不在基类中使用构造函数注入或基于装饰器的注入,而仅在此处手动使用Aurelia的容器实例,从而完全避免继承问题
可能,尽管有一些缺点:* Container.instance的静态访问将提供根容器,这可能不考虑生命周期设置。注入基类的服务可能还具有依赖项*通常,构造函数参数更简洁,并且不会将不必要的DI逻辑混入类*手动访问会增加复杂性,对于每个参数,必须添加container.get(Foo)