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();
}
}
我有这个配置文件,它有数据接口、滚动条的默认配置、能够注入此配置的注入令牌和包含工厂的模块提供程序,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();
}
}