【问题标题】:Pattern to enable customization through DI通过 DI 启用自定义的模式
【发布时间】:2017-02-20 14:57:00
【问题描述】:

我在看in-memory-web-api的实现,有如下代码:

@Injectable()
export class InMemoryBackendService {
  protected config: InMemoryBackendConfigArgs = new InMemoryBackendConfig();
            ^^^^^^
  ...

      constructor(
        @Inject(InMemoryBackendConfig) @Optional() config: InMemoryBackendConfigArgs 
                                                   ^^^^^^
        ) {
        ...

据我了解,模式如下:

  1. 定义类属性并在不使用 DI 的情况下实例化依赖项
  2. 可选择注入依赖项

如果用户通过 DI 提供修改后的依赖项,它将被注入,并且默认的没有 DI 的实例化的依赖项将被覆盖。我怀疑HTTP 模块中的RequestOptions 可能有类似的东西。

这是一种常见的模式吗?

编辑

事实证明,in-memory-web-api 并不是我要询问的模式。假设,我有一个类A,它使用类B 的实例,可通过令牌B 注入。所以他们都注册了根注入器:

提供者:[A, B]

现在,如果用户想要自定义B,他可以在同一个令牌下注册自定义版本,从而有效地覆盖原来的B

providers: [{provide:B, useClass: extendedB}]`

这就是RequestOptions 可以在http 模块中扩展的方式。

【问题讨论】:

    标签: angular angular2-di


    【解决方案1】:

    默认值不只是被覆盖。 most important part 这里是

    Object.assign(this.config, config || {})
    

    没有它什么都不会发生。

    此模式并非特定于 DI,它是默认属性值的常见配方,类似于 _.defaults

    我想说InMemoryBackendConfig default implementation 在这里是无用的抽象。由于this.config 总是与config 合并,所以前者可能只是一个普通对象

      protected config: InMemoryBackendConfigArgs = { ... };
    

    InMemoryBackendConfigRequestOptions 使用这种模式的复杂变体。是的,在最基本的形式中,这是可以做到的:

    providers: [{provide:B, useClass: extendedB}]`
    

    这种模式被 AngularJS 中的constant 服务广泛用于配置对象,但是将B 作为类而不是普通对象允许扩展原始值而不是替换它们。

    【讨论】:

    • 是的,谢谢,我错过了他们没有在构造函数中为config 提供访问修饰符。所以这是不同的模式。 http 模块的 RequestOptions 的例子更重要。让我编辑问题。
    • 顺便问一下,你的linkedin账号是什么?
    • 实际上,我认为 RequestOptions 是一个更复杂的版本,而且非常独特。而不是assign,它与merge method 进行更复杂的合并。它以a service 的形式提供,但通过another helper function 使用..
    • 我已经更新了答案。是的,您建议的模式应该可以这样工作。我个人会坚持使用可注入类来配置对象。 Angular 内置插件并不是最好的例子,因为它们也是直接用 new 实例化的,这并没有让事情变得更简单。
    猜你喜欢
    • 1970-01-01
    • 2019-04-04
    • 2015-01-26
    • 2014-01-01
    • 2018-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-09
    相关资源
    最近更新 更多