I have a Play application and I'm using the Play libraries for DI, with Guice out of the box.
Some of the play modules I'm defining, depend on each other, and in order for them to be able to inject one's bindings in another, I'm trying to keep a reference to the Play injector in a Global place, i.e.
class MyApplicationLoader extends GuiceApplicationLoader() {
override def builder(context: ApplicationLoader.Context):
GuiceApplicationBuilder = {
val builder = super.builder(context)
Global.Injector = builder.injector()
builder
}
}
This works well while Play runs in Dev mode, but in Production mode, the call Global.Injector = builder.injector()
causes circular dependency because it invokes modules and bindings that needs Global.Injector
to be initialized, but it wasn't yet initialized at this point.
I understand it may be related to the fact that in Dev mode, eager singletons are initialized first whereas in Production mode, eager singletons & regular singletons are initialized together.
I'm trying to keep a reference to the Play injector in a Global place
This should be unnecessary in most cases, and you should try to avoid it.
For solving your issue, it looks like you only need to use the Provides annotation, a simple example is like this:
class MyModule extends AbstractModule {
@Provides
def complexConstructor(a: ObjA, b: ObjB): ComplexClass = ???
}
This approach should not have any issues.