1

我有一个使用了两个辅助类中的一个,像一个组件:如何注入辅助类动态

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是真是假。

+0

更新'HelperA'和'HelperB'的代码 – Aravind

+0

如何将他们重构为基类?没有注射,他们总是在那里,等我的问题,你有什么问题与测试? – SayusiAndo

+0

我不能嘲笑直接导入的类(据我所知) –

回答

3

你可以将所有这些都推送到注射器。假设两个帮手有一个共同的超类命名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); 
    } 
} 

注意,这将是在组件的提供程序数组中,因为元素引用在模块级别不可用。

+0

最有可能的ElementRef值应该传入工厂方法 –

+0

我可以稍后传递元素ref(不是构造函数),这会使它更容易 –

+1

@JeanlucaScaljeri是的,你可以有例如'this.helper.setRef(this.ref);'在某些时候如果DI不起作用;如果你忘记在某个地方这样做,那么你将对象置于不可用状态。 – jonrsharpe