Angular DI和继承:注入基础服务的扩展 [英] Angular DI and inheritance: injecting extensions of a base service

查看:135
本文介绍了Angular DI和继承:注入基础服务的扩展的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个基本服务和两个继承服务:

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

    推荐答案

    SomeServiceAnotherService继承了BaseService的装饰器元数据,因此angular将BaseService的实例插入其位置.

    SomeService and AnotherService inherit the decorator metadata from BaseService, so angular injects an instance of BaseService in their place.

    这很危险,因为从SomeServiceAnotherService调用任何实例成员(不是从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和继承:注入基础服务的扩展的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆