【问题标题】:Injection via the constructor parameters vs. the Injector service通过构造函数参数与 Injector 服务进行注入
【发布时间】:2020-04-18 04:17:44
【问题描述】:

我现在使用 Angular2/4 几个月了,但我仍然无法弄清楚这两种方法之间有什么区别,以及关于依赖注入我应该使用哪一种

你能帮帮我吗?

第一种方法:通过构造函数

...
  constructor(
    private myService: MyService
  ) { 
    // this.myService.myMethod() ...
  }
...

第二种方法:通过注射器

...
  private myService: MyService;

  constructor(
    injector: Injector
  ) {
    this.myService = injector.get(MyService);
    // this.myService.myMethod() ...
  }
...

我了解每种方法的作用,但我无法找出最佳实践。

我知道这可能是一种主观意见,但我认为两者各有利弊。

感谢您的任何解释。

【问题讨论】:

  • 你的第二种方法有both;注入器是通过构造函数注入提供的。另请注意,文档告诉您:angular.io/guide/…
  • 我不是 DI 专家,但在第一种方法中,当我们创建 component 实例时,通过检查 constructor 参数来查找 this 组件所需的依赖项。这在许多情况下都很好,但在第二种方法中,您注入整个DI Container,其中包括所有服务,但并非在所有情况下都需要。请检查此link
  • @jonrsharpe。谢谢,您的链接很有帮助。
  • @N.HariHaraSudhan :谢谢,我不确定它是否有真正的区别,因为一切都是通过引用传递的,不是吗?但我认为你是对的:第一种方法更好......仅仅是因为,观察构造函数,你可以快速判断需要哪些依赖项。

标签: angular dependency-injection


【解决方案1】:

你应该总是更喜欢第一个选项:

...
  constructor(
    private myService: MyService
  ) { 
    // this.myService.myMethod() ...
  }
...

第二种方法有效,因为当您注入MyService 时,它是使用Injector 注入的。

Angular 使Injector 可用于注入,因为您可能需要在动态实例化模块或组件时使用它:

组件:

export class ModuleLoaderComponent {
  constructor(private _injector: Injector,private loader: NgModuleFactoryLoader) { ... }

  ngAfterViewInit() {
    this.loader.load('app/t.module#TModule').then((factory) => {
      const module = factory.create(this._injector);  <-----------------

模块:

export class RouterConfigLoader {

  load(parentInjector, route) {
    ...
    const modFactory = this.loadModuleFactory(route.loadChildren);
    const module = modFactory.create(parentInjector);
  }

您可以在以下文章中阅读有关动态实例化的更多信息:

正如@estus 所指出的,injector 也用于在构造函数中注入依赖项导致循环依赖项或您希望根据某些条件获得依赖项的情况。

【讨论】:

【解决方案2】:

有人告诉我,使用构造函数方法进行依赖注入通常会更好。它准确地告诉你这个类需要什么。

另一方面,在某些情况下,您最好使用注射器。除了动态实例化之外,您还必须考虑类继承 假设您希望从一个基础组件构建一个组件,该基础组件引入了同样基于其他服务 S1 的服务 S2。即 C1(S1) 中的 C2(S2)。

通常,C2 使用 super 实例化 C1,看起来像这样

constructor(
    private service2: S2
  ) { 
    super(S1)
  }

我发现必须调用父服务 S1 和 S2 才能构建 C2。如果S1使用injector方法就不会那么纠结了,这样写C2就这么简单了

constructor(
    private injector: Injector
  ) { 
    super()
    this.service2 = this.injector.get(S2)
  }

private service2: S2

如果您想放弃在构造函数中设置实例,您可以更进一步并创建自己的注入器单例。看 this article

【讨论】:

    猜你喜欢
    • 2013-01-11
    • 1970-01-01
    • 1970-01-01
    • 2022-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多