【问题标题】:Trouble injecting service into another service (singleton), Angular2无法将服务注入另一个服务(单例),Angular2
【发布时间】:2017-07-05 19:40:51
【问题描述】:

我有两个服务,都是@Injectable。 ServiceA 通过 Providers 数组提供给组件,并且在任何地方都很好用。 ServiceB 是一个单例,位于其模块的 Providers 数组中,并且在任何地方都可以很好地工作。 ServiceA 需要保持不是单例,ServiceB 需要保持单例。

我的问题是现在我需要从 ServiceB 访问 ServiceA,但不知道如何访问它。似乎我无法将非单例服务注入单例。

我遇到的所有事情都告诉我将服务放入引导程序或模块声明中,但正如我所提到的,我不能这样做,因为我需要 ServiceA 充当非单例。

// module setup
... providers: [ServiceB]

// non-singleton
@Injectable()
export class ServiceA

// singleton
@Injectable()
export class ServiceB {
  constructor(ServiceA)  // <-- this is the problem area, need to get ServiceA here

我尝试过类似 constructor(Inject(ServiceA) serviceA) 的操作,但似乎遇到了同样的错误

错误:DI 错误 没有 ServiceA 的提供者!

  1. 如何将非单例服务“提供”到单例服务中,其中两者都是 @Injectable?

【问题讨论】:

    标签: angular typescript dependency-injection


    【解决方案1】:

    您可以在@Component.providers@NgModule.providers 中声明ServiceA

    • 在组件的构造函数中注入ServiceA 时,您将获得组件范围的实例(对应于@Component.providers 声明)。
    • 在另一个服务的构造函数中注入ServiceA 时(在您的情况下:在ServiceB 中注入ServiceA 时),您将获得全局实例(对应于@NgModule.providers 声明)。

    换句话说,如果您在组件的提供者 (@Component.providers) 中重新声明服务,它将“隐藏”在 @NgModule.providers 中全局声明的实例。

    注意事项:

    • 如果将ServiceA 注入ServiceBServiceC,则B 和C 将获得相同的A 实例。
    • Seaal 在 cmets 中提到,以这种方式组织代码可能不符合最佳实践。

    【讨论】:

    • 非常感谢@AngularFrance,现在可以解决问题了。我注意到你的谨慎和同样的想法,但一定有办法解决这个问题,但不是吗?我认为这可能会导致问题...理论上你应该能够将非单例注入单例而不引起任何问题,可惜 Angular2 没有提供一个好的方法。
    • 不客气。绕过上述限制的另一种方法可能是重构您的代码。我想您需要您的服务是非单例的,因为每个服务实例必须具有不同的状态/数据。也许您可以让服务成为单例,同时手动维护服务内部多个状态的注册表。只是大声思考,不确定这是否适用于您的情况。
    • 将非单例注入单例是一种代码异味。如果您希望将ServiceA 的不同实例创建到多个其他服务中,您可以直接使用Angular2 Injector(最好在工厂类中)。
    • @Seaal ah cool 直接使用 Injector 看起来是正确的长期解决方案。至于您的代码异味评论,我认为在这种情况下这是适当的设置。基本上我有一个数据工厂,它是一个单例,它可以让所有人都可以访问来自服务器的最新数据模型,并通过休息促进 crud 操作。然后我有那个非单例来管理套接字通信,我希望能够将它的数据与单例的数据结合起来,然后在多个组件中使用它(这就是为什么我想在服务而不是组件中这样做)跨度>
    猜你喜欢
    • 1970-01-01
    • 2017-06-27
    • 1970-01-01
    • 1970-01-01
    • 2019-10-22
    • 2013-12-22
    • 2017-01-17
    • 1970-01-01
    相关资源
    最近更新 更多