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

Angular 2 DI injects same instance of clonned object with factory when I need own instance for each injection

我有这个配置文件,它有数据接口、滚动条的默认配置、能够注入此配置的注入令牌和包含工厂的模块提供程序,returns 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,但随后 returns 每次注入都会使用相同的克隆对象。我也尝试通过创建 class 而不是注入令牌来做到这一点,但它的行为是一样的。

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

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

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

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

由于服务永远不应该被重用并且是单例的,它可以是 class 定义为 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();
  }
}