【问题标题】:Is [providers] necessary when doing constructor dependency injection?进行构造函数依赖注入时是否需要 [providers]?
【发布时间】:2017-11-04 07:13:55
【问题描述】:

通过这个todo tutorial,它有以下内容:

 import {TodoDataService} from './todo-data.service';

 @Component({
  // ...
   providers: [TodoDataService]
 })

 constructor(private todoDataService: TodoDataService) {
 }

IIUC 我们必须在 providers 数组中声明 TodoDataService。这似乎是多余的。 Angular DI 能否读取组件生成的元数据并使用构造函数注入自动注入TodoDataService

更新

Angular 已经在some extent now 上实现了这一点。我要求他们也删除providedIn:root,他们说他们在路线图上有一些东西。

【问题讨论】:

  • 您需要告诉它应该为该令牌注入什么;在模块的提供者数组或组件的提供者数组中。
  • Spring 在 4.3 中使其自动运行。我想知道 Angular 是否会更简单地默认为类似类型的机制,如果需要更多细节/自定义,则允许进一步自定义:spring.io/blog/2016/03/04/…
  • 还打开了 Angular 问题:github.com/angular/angular/issues/17182
  • 是的,它可以读取。不,它不应该读。无法控制注入的内容会给开发人员带来非常糟糕的体验。有分层注入器。有多种提供者类型。这将只是一场噩梦。
  • 为什么它适用于 Spring?

标签: angular typescript angular-decorator


【解决方案1】:

来自Angular.io docs

喷油器冒泡

当一个组件请求一个依赖项时,Angular 会尝试使用在该组件自己的注入器中注册的提供程序来满足该依赖项。如果组件的注入器缺少提供程序,它会将请求传递给其父组件的注入器。如果该注入器不能满足请求,它将把它传递给它的父注入器。请求不断冒泡,直到 Angular 找到可以处理请求的注入器或用完祖先注入器。如果它的祖先用完了,Angular 会抛出一个错误。

我对此的理解是,如果您的组件提供服务,您将获得该服务的一个实例每个组件。如果没有,它会沿着组件树向上走,直到找到可以提供它的东西。所以一些东西必须提供它。

我认为它实际上确实检查了生成的元数据,但它只是使用它来查看组件需要什么服务,而不是服务来自哪里(这就是 providers:[TodoDataService] 的用途) .

在我的应用程序中,我的大部分服务都在我的app.module.ts 中提供,因此我在整个应用程序中获得每个服务的一个实例。

【讨论】:

  • 我明白了。我只是好奇Angular是否可以自动执行构造函数注入,因为它会为组件生成元数据?在 github 问题中提供了更多详细信息。我们几乎总是想要一个通过构造函数注入注入的服务的单例实例。 Angular 为组件生成元数据,因此它可以读取装饰器并确定这是设计者的意图,而无需进一步配置。
  • 可以,但这可能是一个糟糕的设计决策。如果你需要一个全局单例,那不就是一个静态类吗?如果每个组件都需要一个单例,那不只是一个实例吗? DI 似乎适用于两者之间的一切。
  • 我确实理解希望没有大量提供商的愿望。您应该将其格式化为 angular/angular github 上的功能请求。
  • 全局单例也可以是静态类,但在服务的情况下,它们很可能是需要初始化的实例,例如 GraphQL 提供程序、PouchDB 提供程序等。
  • 对于包含实用方法的静态类,我们根本不需要 DI。我们应该从 RxJS 等库中导入这些实例。我在这里写了一个关于如何生成 vanilla typescript 库的示例:stackoverflow.com/questions/44165084/…
猜你喜欢
  • 2011-02-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-16
  • 2019-04-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多