Circular dependency between services


#1

Hi, I’m curious how Ember handles circular dependencies between services.

Simple example:

  • Service A requires service B
  • Service B requires service A

(with “requires”, I mean “is injected”)

When my component uses service A, will it work as expected? When my tests mock some of the services, will it work as well?

Thank you


#2

Ember uses lazy loading and services are singletons. In your description when A does a this.get('B') it will either return the one B instance in the app or create it for the first time. B does not evaluate A until some action in there requests it. Even if both ask for eachother in their init() since services are singeltons these methods are only ever evaluated once. There is no recursion here because 1) the resolution of a service is at the time of the this.get (lazy-resolve) and 2) the resolution is one instance app wide.


#3

You were a little bit optimistic about the code base. I just wanted to know if it’s really that good but actually it’s not working. An InternalError: too much recursion is thrown. https://ember-twiddle.com/d886ea54b28804f8efd253d69e3cdcaa?numColumns=3&openFiles=controllers.application.js%2Cservices.foo.js%2Cservices.bar.js


#4

Yeah, it’s possible to hit a problem if both are trying to access each other immediately at creation. But in practical situations, that is rarely needed. As long as one of the services only access the other on-demand, later than init, it should be fine.

And if two services really are bi-directionally entangled during init, they probably should be one service, not two.