【问题标题】:How does Angular2 manage dependency injection?Angular2 如何管理依赖注入?
【发布时间】:2017-01-17 11:25:31
【问题描述】:

我知道要将依赖项注入到 Angular2 组件中,我只需在其构造函数中注释一个参数,就像这里使用 ThingService 一样。我想了解的是 Angular 如何知道在运行时注入什么,据我所知,这只是 TypeScript 注释,在运行时没有任何意义。什么是低级别的内部机制,用于管理哪些提供程序放置在组件的构造函数中的哪个位置。如果您要自己推出这个系统,它将如何工作。这是我不理解的打字稿机制吗?

@Component({
  selector: 'app-thing',
  templateUrl: './thing.component.html',
  styleUrls: ['./thing.component.scss']
})
export class ThingComponent {

  constructor(
    private thingService: ThingService) {
  }
}

【问题讨论】:

标签: javascript angular typescript


【解决方案1】:

在底层发生的事情是 TypeScript 在生成的 ES5 代码中保留了元数据。所以构造函数中的注释实际上并没有消失,它在运行时可用,然后 Angular 的 DI 可以从那里获取它。

如果满足以下要求,TypeScript 始终会保留该元数据:

  1. 编译器选项属性 - emitDecoratorMetadataexperimentalDecorators - 需要设置为 true
  2. 类中必须至少有一个装饰器(这就是为什么一些服务类使用@Injectable() 装饰器,否则它们的依赖项的元数据将不会被发出)

我已经写了一篇关于该主题的深入文章here

【讨论】:

    【解决方案2】:

    如果我理解正确,您要求的是更理论化的(ts 后面的 js)答案。

    根据我的阅读; angular2 注入系统创建该提供程序对象/函数的实例,并在您像在构造函数中那样定义它时在该组件中使用该实例。如果您没有在您正在使用的组件中提供它,那么它将转到它的父组件,直到它被使用的模块。每个级别都有自己的提供程序实例映射,组件将使用它在向上遍历注入树时找到的第一个实例。

    所以提供者将是一个单例实例,直到它被定义。

    【讨论】:

    • 我正在寻找一种机制,Angular 用它来识别哪些提供者将在组件构造函数中按什么顺序放置
    • @MildFuzz 您的意思是,如果您向构造函数添加另一个服务,它将首先调用哪个服务?像一个循环依赖问题?
    • 如果我有另一个服务并注入它,Angular 怎么知道 ThingService 应该是构造函数中的第一个参数,而不是第二个?
    • @MildFuzz 这与您在构造函数中定义的顺序相同。我感觉你有一个依赖周期问题
    • 是的,但是怎么做?据我所知,类型注释在运行时没有任何意义。我怎样才能定义一个类,并动态地知道它所期望的依赖关系?这似乎正在发生。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-16
    • 1970-01-01
    • 2017-04-26
    • 2016-07-20
    • 1970-01-01
    相关资源
    最近更新 更多