【问题标题】:How to conditionally inject service into component?如何有条件地将服务注入组件?
【发布时间】:2017-09-12 23:58:49
【问题描述】:

我有两个服务one.service.tstwo.service.ts,还有一个组件dashboard.component.ts

如何有条件地将这些服务注入到组件中?

import { Component, ViewEncapsulation, Inject } from '@angular/core';
import { OneService } from '../services/one.service';
import { TwoService } from '../services/two.service';

@Component({
  selector: 'dashboard',
  encapsulation: ViewEncapsulation.Emulated,
  styleUrls: ['./dashboard.less'],
  templateUrl: './dashboard.html'
})
export class DashboardComponent {
    constructor() {
       // Here how do I get service instance based on some this condition.
         if(true) {
             /* Service **one.service.ts** to be injected */
         } else {
             /* Service **two.service.ts** to be injected */    
         }

    }
}

【问题讨论】:

  • 使用useFactoryinjector.get
  • 或者创建 DashboardComponent 的特定实例。这个组件多态到使用两个服务的地步,这似乎很奇怪。当然,我可能错了,因为我们错过了域上下文

标签: angular dependency-injection angular2-services


【解决方案1】:

您可以使用Injector

import { Injector } from '@angular/core'  
...
constructor(private injector: Injector){ 

  if(true) {
    this.oneService = <OneService>this.injector.get(OneService);
  } else {
    this.twoService = <TwoService>this.injector.get(TwoService);
  }
}

正如@MeirionHughes 所说,这被称为服务定位器模式:

该技术是服务定位器模式的一个示例。

避免这种技术,除非你真的需要它。它鼓励一种粗心的抓包方法,就像你在这里看到的那样。很难解释、理解和测试。通过检查构造函数,您无法知道此类需要什么或它将做什么。它可以从任何祖先组件获取服务,而不仅仅是它自己的。您不得不深入研究实现以发现它的作用。

框架开发人员在必须通用且动态地获取服务时可能会采用这种方法。

来源:https://angular.io/docs/ts/latest/guide/dependency-injection.html#!#explicit-injector

如上所述,您可以在另一个服务中获取这些注入器,然后将该服务注入到您的组件中。

【讨论】:

  • 抱歉,这是一种不好的做法,您正在打破 IoC 范式,这是您首先拥有(可注入)服务的唯一原因。答案在技术上非常好(我从中学到了),但我不得不投反对票
  • 我已经删除了我的反对票(它至少作为最后的手段很有用)但我建议人们查找制作 Provider/Builder/Factory/Facade 并避免使用 injector.get()
【解决方案2】:

换句话说,您要实现BridgeAbstract Factory 模式。在这种情况下,您可以使用useFactory。相关post

【讨论】:

    猜你喜欢
    • 2016-02-10
    • 1970-01-01
    • 2017-01-07
    • 2018-08-22
    • 2018-05-20
    • 1970-01-01
    • 2020-01-06
    • 1970-01-01
    相关资源
    最近更新 更多