Angular DI 和继承:注入基础服务的扩展 [英] Angular DI and inheritance: injecting extensions of a base service
问题描述
我有一个基本服务和两个继承服务:
@Injectable({ providedIn: 'root' })导出类 BaseService {foo(src?: 字符串){从 ${src || 返回`'基础服务'}`;}}@Injectable({providedIn: 'root' })导出类 SomeService 扩展了 BaseService {富(){return super.foo('SomeService')}}@Injectable({providedIn: 'root' })导出类另一个服务扩展了 BaseService {富(){return super.foo('AnotherService')}}
我希望将它们注入某个组件并检索三个独立类的实例:
@Component({选择器:'我的应用',模板:`<div><p>谁在那里?</p><p>{{ base }}</p><p>{{一些}}</p><p>{{另一个}}</p>
`,})出口类应用{基础:字符串;一些:字符串;另一个:字符串;构造函数(基础:BaseService,一些:SomeService,另一个:AnotherService){this.base = base.foo();this.some = some.foo();this.another = another.foo();}}
相反,我得到了同一个类的三个实例(HTML 输出):
谁在那里?来自 BaseService来自 BaseService来自 BaseService
- 为什么这不起作用?
- 为什么 SomeService、AnotherService 和 BaseService 不是 Angular DI 的唯一令牌?
好像放了
<代码>...{ 提供: SomeService , useClass: SomeService },{提供:AnotherService,useClass:AnotherService},...
在提供程序中将使其工作.
- 为什么明确需要这样做?
一个 plnkr:https://next.plnkr.co/edit/BvmppLHRbFbz9CFZ
SomeService
和 AnotherService
继承了 BaseService
的装饰器元数据,所以 angular在它们的位置注入 BaseService
的一个实例.
这是危险的,因为从 SomeService
或 AnotherService
调用任何不是从 BaseService
继承的实例成员都会触发运行时错误.
归档您正在寻找的行为的最简单方法是从公共抽象基类继承,没有装饰器:
导出抽象类 AbstractBaseService {foo(src?: 字符串) {从 ${src || 返回`'AbstractBaseService'}`;}}@Injectable({providedIn: 'root' })导出类 BaseService 扩展 AbstractBaseService {富(){return super.foo('BaseService');}}@Injectable({providedIn: 'root'})导出类 SomeService 扩展 AbstractBaseService {富(){return super.foo('SomeService');}}@Injectable({providedIn: 'root' })导出类 AnotherService 扩展 AbstractBaseService {富(){return super.foo('AnotherService');}}
我修改了您的 plnkr 以测试这种方法.
I have a base service and two inhering services:
@Injectable({ providedIn: 'root' })
export class BaseService {
foo(src?: string){
return `speaking from ${src || 'BaseService'}`;
}
}
@Injectable({ providedIn: 'root' })
export class SomeService extends BaseService {
foo(){
return super.foo('SomeService')
}
}
@Injectable({ providedIn: 'root' })
export class AnotherService extends BaseService {
foo(){
return super.foo('AnotherService')
}
}
I wish to inject them in some component and retrieve instances of the three separate classes:
@Component({
selector: 'my-app',
template: `
<div>
<p>Who's there?</p>
<p>{{ base }}</p>
<p>{{ some }}</p>
<p>{{ another }}</p>
</div>
`,
})
export class App {
base: string;
some: string;
another: string;
constructor(base: BaseService, some: SomeService, another: AnotherService) {
this.base = base.foo();
this.some = some.foo();
this.another = another.foo();
}
}
Instead, I get three instances of the same class (HTML output):
Who's there?
speaking from BaseService
speaking from BaseService
speaking from BaseService
- Why doesn't this work?
- Why are SomeService, AnotherService and BaseService not unique tokens for Angular DI?
It seems that putting
...
{ provide: SomeService , useClass: SomeService },
{ provide: AnotherService , useClass: AnotherService },
...
in the providers will make it work.
- Why is this explicitly needed?
A plnkr: https://next.plnkr.co/edit/BvmppLHRbFbz9CFZ
SomeService
and AnotherService
inherit the decorator metadata from BaseService
, so angular injects an instance of BaseService
in their place.
This is dangerous, as calling any instance member from either SomeService
or AnotherService
which isnt inherited from BaseService
will trigger a run-time error.
The simplest way to archive the behavior you are looking for, would be to inherit from a common abstract base class, with no decorator:
export abstract class AbstractBaseService {
foo(src?: string) {
return `speaking from ${src || 'AbstractBaseService'}`;
}
}
@Injectable({ providedIn: 'root' })
export class BaseService extends AbstractBaseService {
foo() {
return super.foo('BaseService');
}
}
@Injectable({ providedIn: 'root'})
export class SomeService extends AbstractBaseService {
foo() {
return super.foo('SomeService');
}
}
@Injectable({ providedIn: 'root' })
export class AnotherService extends AbstractBaseService {
foo() {
return super.foo('AnotherService');
}
}
I modified your plnkr to test this approach.
这篇关于Angular DI 和继承:注入基础服务的扩展的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!