【问题标题】:How to inject helper class dynamically如何动态注入助手类
【发布时间】:2018-02-04 20:19:07
【问题描述】:

我有一个使用两个辅助类之一的组件,例如:

import {HelperA} ...
import {HelperB} ...
...

@Component({..})
export class MyComponent implements OnInit {
    helper: Helper;     
    constructor(private ref: ElementRef, private device: MyDeviceDetectionService) {}

    ngOnInit() {
        if (this.device.isMobile) {
            this.helper = new HelperA(this.ref);
        } else {
            this.helper = new HelperB(this.ref);
        }
    }
}

我意识到这很难进行单元测试,那么我该如何注入这些呢?理想情况下,我只需要其中一个,具体取决于isMobile 是真还是假。

【问题讨论】:

  • 更新HelperAHelperB的代码
  • 将它们重构为基类怎么样?没有注射,它们总是在那里,等等。我的问题,你的测试有什么问题?
  • 我无法模拟直接导入的类(据我所知)

标签: angular unit-testing typescript dependency-injection angular2-di


【解决方案1】:

您可以将所有这些都推到注射器中。假设这两个助手有一个名为 Helper 的公共超类,请使用 useFactory 提供程序选项来创建您需要的任何一个:

providers: [
  ...,
  { provide: Helper, useFactory: createHelper, deps: [MyDeviceDetectionService, ElementRef] },
]

那么工厂应该是这样的:

export function createHelper(device: MyDeviceDetectionService, ref: ElementRef): Helper {
  if (device.isMobile) {
    return new HelperA(ref);
  } else {
    return new HelperB(ref);
  }
}

请注意,这必须在 组件的 providers 数组中,因为元素引用在模块级别不可用。

【讨论】:

  • 很可能应该将 ElementRef 值传递给工厂方法
  • 我可以稍后传入元素 ref(不是构造函数),这样会更容易
  • @JeanlucaScaljeri 是的,你可以有例如this.helper.setRef(this.ref); 在某些时候如果 DI 不起作用;这样做的缺点是,如果您忘记在某处这样做,那么您会使对象处于不可用状态。
  • @jonrsharpe 你不能在那里使用ElementRef,它是本地编译器依赖,在根注入器中没有意义。此提供程序应在组件的providers 中指定,而不是在模块中。
  • @JeanlucaScaljeri 我做到了,是的;固定的。为什么不让它成为一个超类呢?否则,您将不得不使用 InjectionToken:angular.io/guide/dependency-injection-in-action#injectiontoken
猜你喜欢
  • 2015-10-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多