当我每次注入需要自己的实例时,Angular 2 DI会使用工厂注入相同的clonned对象实例

时间:2017-05-31 13:12:48

标签: angular typescript dependency-injection factory

我有这个Config文件,它有数据接口,滚动条的默认配置,能够注入此配置的注入令牌以及包含返回默认配置对象的deepClone的工厂的模块的提供者:

export interface ScrollbarConfig {
    name: string;
    class: string;
    options: MCustomScrollbar.CustomScrollbarOptions;
}

export const SCROLLBAR_CONFIG = new InjectionToken<ScrollbarConfig>('scrollbar.config');`

export const SCROLLBAR_CONFIG_DEFAULT: ScrollbarConfig = { ... }

export const SCROLLBAR_CONFIG_PROVIDER = {
    provide: SCROLLBAR_CONFIG,
    useFactory: () => {
            return _.cloneDeep(SCROLLBAR_CONFIG_DEFAULT);
        }
};

这是我的模块添加提供程序的方法:

providers: [
        SCROLLBAR_CONFIG_PROVIDER
    ]

这就是我在组件的构造函数中注入它的方式:

constructor(@Inject(SCROLLBAR_CONFIG) private scrollbarConfig: ScrollbarConfig) {}

因此,我们的想法是获取滚动条的默认配置,然后在每个组件中扩展注入的对象,因此每个组件都有自己的配置。但由于某种原因注射给我同样的实例,即使我使用提供者与工厂。我很确定它会生成一个默认对象的deepClone,但是每次注入都会返回相同的clonned对象。我也尝试过创建类而不是注入令牌,但它表现得一样。

我尝试将console.log()放在工厂函数中,它只打印一次,所以很明显这是问题所在,但我怎么能强制它真正提供不同的实例呢?

1 个答案:

答案 0 :(得分:1)

提供程序是单个注入器中的单例,当在模块providers中定义服务时,它属于根注入器(或延迟加载模块的子注入器)。

为了让所有组件都能接收自己的实例,应该为这些组件类指定providers(而不是模块类):

@Component({ ..., providers: SCROLLBAR_CONFIG_PROVIDER }) ...

由于服务永远不应该被重用并且是单例,因此它可以是定义为useValue提供者的类:

export class ScrollbarConfig {
  name: string = ...;
  class: string = ...;
  // or
  // constructor() {
  //   return _.cloneDeep(SCROLLBAR_CONFIG_DEFAULT)
  // }
}

@Module({ ..., providers: { provide: ScrollbarConfig, useValue: ScrollbarConfig }) ...

@Component(...)
class SomeComponent {
  scrollbarConfig: ScrollbarConfig;

  constructor(@Inject(ScrollbarConfig) ScrollbarConfig: typeof ScrollbarConfig) {
    this.scrollbarConfig = new ScrollbarConfig();
  }
}