Angular 如何动态注入helper类

Angular 如何动态注入helper类,angular,unit-testing,typescript,dependency-injection,angular2-di,Angular,Unit Testing,Typescript,Dependency Injection,Angular2 Di,我有一个使用两个助手类之一的组件,如: import {HelperA} ... import {HelperB} ... ... @Component({..}) export class MyComponent implements OnInit { helper: Helper; constructor(private ref: ElementRef, private device: MyDeviceDetectionService) {} ngOnI

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

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
是否为真

您可以将所有这些都推到喷油器上。假设这两个助手有一个名为
Helper
的公共超类,请使用
useFactory
provider选项来创建所需的:

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);
  }
}

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

更新
HelperA
HelperB
的代码,如何将它们重构为基类?没有注入,它们总是在那里,等等。我的问题是,测试有什么问题?我不能模拟直接导入的类(据我所知),最有可能的是ElementRef值应该传递到工厂方法中,我可以稍后传递element ref(而不是构造函数),这将使easier@JeanlucaScaljeri对您可以拥有例如
this.helper.setRef(this.ref)在某个点;这样做的缺点是,如果您忘记在某个地方执行此操作,则会使对象处于不可用状态。@jornsharpe如果您不能在那里使用
ElementRef
,则在根注入器中没有意义的是本地编译器依赖关系。此提供程序应该在组件的
提供程序中指定,而不是在模块中指定。@JeanlucaScaljeri,是的;固定的。为什么不让它成为一个超类呢?否则,您将不得不使用InjectionToken: