I have this binding to configure the Logger[IO] in my app (module with this line is in guice.conf file):
class CatsEffectModule extends AbstractModule with ScalaModule {
override def configure(): Unit = {
bind[Logger[IO]].toInstance(Slf4jLogger.getLogger[IO])
}
}
Then in the app i can do this:
@Singleton
class MyClass @Inject()(implicit logger: Logger[IO]) { ... }
And this works fine in the application.
But it won't work when used in GuiceInjectorBuilder
(for tests):
import play.api.inject.guice.GuiceInjectorBuilder
private val application: Injector = new GuiceInjectorBuilder()
.bindings(bind[ExecutionContext].to(ExecutionContext.global))
.bindings(bind[ApplicationLifecycle].to[DefaultApplicationLifecycle])
.bindings(new CatsEffectModule())
.build()
application.instanceOf[MyClass]
It gives me an error:
No implementation for io.chrisdavenport.log4cats.Logger was bound.
[info] Did you mean?
[info] io.chrisdavenport.log4cats.Logger<cats.effect.IO> bound at guice.CatsEffectModule.configure(CatsEffectModule.scala:21) (via modules: com.google.inject.util.Modules$OverrideModule -> guice.CatsEffectModule)
And every TF-entity injection in tests fails like this. Is there some difference between how Akka Play runs Guice and how GuiceInjectorBuilder works?
Code example: https://github.com/DenisNovac/play-tf-test
The Scala-guice by codingwell (https://github.com/codingwell/scala-guice) allows to bind TF-classes (it is made for vanilla Guice, not the Play Guice). They will be binded to dependent classes correctly, but the
GuiceInjectorBuilder
won't let you get it byinstanceOf
method.But it seems that it works in both directions if you use both binds:
Perhaps there is a way to make scala-guice and play work together but i got no luck with it.
Full example: https://github.com/DenisNovac/play-tf-test