问题描述
我有一个基本服务和两个继承服务:
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();
}
}
相反,我得到了三个相同类的实例(HTML输出):
Instead, I get three instances of the same class (HTML output):
Who's there?
speaking from BaseService
speaking from BaseService
speaking from BaseService
- 为什么这行不通?
- 为什么SomeService,AnotherService和BaseService不是Angular DI的唯一标记?
似乎推杆
...
{ provide: SomeService , useClass: SomeService },
{ provide: AnotherService , useClass: AnotherService },
...
提供程序中的
将使其起作用.
in the providers will make it work.
- 为什么这是明确需要的?
一个plnkr: https://next.plnkr.co/edit/BvmppLHRbFbz9CFZ
推荐答案
SomeService
和AnotherService
继承了BaseService
的装饰器元数据,因此angular将BaseService
的实例插入其位置.
SomeService
and AnotherService
inherit the decorator metadata from BaseService
, so angular injects an instance of BaseService
in their place.
这很危险,因为从SomeService
或AnotherService
调用任何实例成员(不是从BaseService
继承的)都会触发运行时错误.
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');
}
}
我修改了plnkr 来测试这种方法.
这篇关于Angular DI和继承:注入基础服务的扩展的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!