【问题标题】:Look up service implementations dynamically动态查找服务实现
【发布时间】:2020-02-19 11:01:01
【问题描述】:

我们的 Angular 应用程序有一个服务,它可以有不同的实现,也就是。 “战略”。为简单起见,我们假设它是一个“事件报告”服务。事件报告服务具有报告信息的功能。根据运行时偏好,报告可以关闭,转到console,或者发送到 REST API,或者转到其他地方。

使用纯 TS,如下所示:

interface IReporter {
  report (message: string): void;
}

class NoReporter implements IReporter {
  report (message: string): void {
    // no op.
  }
}

class ConsoleReporter implements IReporter {
  report (message: string): void {
    console.log(message);
  }
}

// etc.

在消费者中,我会放置一些工厂来提供所需的记者,例如。基于用户偏好设置:

getReporter (key: string): IReporter {
  switch (key) {
    // … tedious cases, which need to be mainted. Yikes!
  }
}

但是,这感觉不太像“Angular”。第一步可能是为各个记者提供适当的 Angular 服务,但仅此一项感觉收效甚微。那么:是否有一些现有的机制可以为我提供以上工厂功能来动态查找实现?有什么要遵循的模式、示例或最佳实践吗?

【问题讨论】:

  • Angulars DI 系统提供 [FactoryProviders ](angular.io/guide/…) 这应该可以完美解决您的问题。
  • @MaxK 完美。非常感谢您的指点! (随时将此作为“正确”答案发布,您会得到我的支持)

标签: angular factory strategy-pattern


【解决方案1】:

就像评论里提到的FactoryProviders完美解决了这个问题。

您必须将IReporter 接口定义为class interface,因为接口在运行时不存在,因此它们不是有效的 DI 令牌:

export abstract class IReporter {
  report: (message: string) => void;
}

@Injectable()
export class NoReporter implements IReporter{
  report(message:string):void{

  }
}

@Injectable()
export class ConsoleReporter implements IReporter {
  report(message: string): void {
    console.log(message);
  }
}

现在您可以创建您的reporterFactoryreporterProvider,如下所示:

const reporterFactory = (key: string) => {
  switch (key) {
    case 'no-report':
      return () => new NoReporter();
    case 'console-report':
      return () => new ConsoleReporter();
    default:
      return () => new ConsoleReporter();
  }
};

export const reporterProvider = (key: string) => {
  return {
    provide: IReporter,
    useFactory: reporterFactory(key)
  }
};

并在你的组件中注入一个记者:

@Component({
  selector: 'test',
  template: `TESTCOMPONENT`,
  providers: [
    reporterProvider('console-report')
  ]
})
export class TestComponent {
  constructor(private reporter: IReporter) {
    reporter.report('it works!!!');
  }

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-15
    • 1970-01-01
    相关资源
    最近更新 更多