【问题标题】:Why my service creates new instance of its dependency?为什么我的服务会创建其依赖项的新实例?
【发布时间】:2019-02-21 10:30:34
【问题描述】:

我有一个包含 2 个组件和 2 个服务 A 和 B 的库。

其中 2 个组件正在使用我的服务 A.. 没问题 - 我可以看到 A 已创建一次 - 我已写信给 ctor 中的 console

服务 B 需要服务 A 来完成他的工作,因此它会注入 A。现在我看到 A 的另一个创建(在控制台中)

服务B在做,和组件做的一样。

import  { A } from './A'
.
.
.
constructor(private myA: A) {...}

但这一次它再次创建了我的服务 A。所以我有 2 个实例。

这对我不好..也很奇怪.. 我在新一代的 Angular 中相对较新 - 一直在为这样的小事情而苦苦挣扎。这令人沮丧。

有人吗?

更新

我已经意识到,当我的客户应用程序延迟加载子模块并在那里导入我的模块时,就会发生这种情况..

例如。

partials.modules.ts

@NgModule({ declarations: [..],exports: [...], imports: [ ..., MyModule ]});
export class PartialsModule {}

pages.module.ts -- 路由懒加载

@NgModule({ declarations: [..],exports: [...], imports: [ ..., PartialsModule ]});
export class PagesModule {}

app.module.ts

@NgModule({ declarations: [..],exports: [...], imports: [ ..., PartialsModule ]});
export class AppModule {}

app 模块正在创建 MyMoudle->my 服务的实例,PagesModule 也是如此。我猜这是因为惰性模块有自己的注入器。

但是我该如何解决呢?

我已尝试使用 forRoot 静态方法将我的模块导入移动到 app.module.ts,如 here 所述。现在partialModule中的组件找不到MyModule(我的库)中的组件

:(

【问题讨论】:

  • @Injectable({ providedIn: 'root' })装饰服务A
  • 我所有的服务都注入了这个。只要我们从其他组件中使用它,该服务就会运行良好。当我从另一个服务中使用它时,它就会发生。然后其他服务创建它..
  • 它是添加到提供者列表中的任何地方还是只是给了上面的装饰器?
  • 我已经在 5 天前发布了它,让它休息一下。现在我再次与您核对,它看起来像我想要的和预期的那样创建了一次服务.. 啊。 ..这个新的角度!无论如何,我想我会在我确认它连续工作几天后很快删除这篇文章:)
  • 幸好我没有删除帖子..检查更新

标签: angular dependency-injection


【解决方案1】:

这里的问题在于您提供服务的哪个级别的组件?

如果您有组件级别的提供程序,您将在每次组件初始化时获得一个实例

那么我建议你添加这个装饰器来指定根模块作为提供者。 @Injectable({ providedIn: 'root' })

或者直接在你需要的模块中指定为: 示例

@NgModule({ declarations: [..],exports: [...], imports: [ ..., MyModule ], providers:[SERVICE_A]});

【讨论】:

  • @Injectable({ providedIn: 'root' }) 写在我所有的服务中。不明白你答案的后半部分。我应该把我的模块导入放在app.module.ts 中吗?我应该使用forRoot() 方式吗?
  • 我们试试下面的做法,在app模块中提供服务,去掉服务装饰器
  • 当我在应用程序中导入myModule - 然后惰性模块无法识别此模块中的组件
  • 尝试这样做,它将为所有应用程序创建一个服务实例:@NgModule({ declarations: [..],exports: [...], imports: [ ..., PartialsModule ], providers:[serivice_A]}); export class AppModule {}
  • 我只把它放在appModule 中的问题是partialsModule 中的组件无法识别myModule 中的组件。
【解决方案2】:

经过几天的努力,我正在分享我找到的解决方案

我的模块中的服务有

// angular 6
@Injectable({
  providedIn: 'root'
})

意味着您的注入将在应用程序中注册为单例,您无需将其添加到根模块的提供者中,更多信息read here

现在,问题.. 我的模块在装饰器中有提供者属性。

@NgModule({
  imports: [...],
  declarations: [...],
  exports: [...],
  providers: [MyService] // <<------- THIS LINE WAS THE PROBLEM - no need for providers in the module
})
export class MyModule { }

只需从模块中删除提供的内容即可解决我的问题。

不需要forRoot 方法。

当我的客户使用我的库并导入我的模块时,它调用模块的 ctor 的次数与导入的次数一样多,但我的服务的 Ctor 被调用一次,这意味着所有服务都共享同一个实例..

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-12-24
    • 2020-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多