Akka Play指南绑定无标签最终(TF)支持



我有这个绑定来配置我的应用程序中的Logger[IO](此行的模块在guide.conf文件中(:


class CatsEffectModule extends AbstractModule with ScalaModule {
override def configure(): Unit = {
bind[Logger[IO]].toInstance(Slf4jLogger.getLogger[IO])
}
}

然后在应用程序中我可以这样做:

@Singleton
class MyClass @Inject()(implicit logger: Logger[IO]) { ... }

这在应用程序中运行良好。

但在GuiceInjectorBuilder(用于测试(中使用时,它不起作用:

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]

它给了我一个错误:

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)

测试中的每个TF实体注入都是这样失败的。Akka Play运行Guice的方式和GuiceInjectorBuilder的工作方式之间有什么区别吗?

代码示例:https://github.com/DenisNovac/play-tf-test

由codingwell编写的Scala指南(https://github.com/codingwell/scala-guice)允许绑定TF类(它是为香草Guice制作的,而不是Play Guice(。它们将被正确地绑定到依赖类,但GuiceInjectorBuilder不允许您通过instanceOf方法获得它。

但如果你同时使用两种绑定,它似乎在两个方向上都有效:

import cats.effect.IO
import com.google.inject.AbstractModule
import net.codingwell.scalaguice.ScalaModule
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers
import play.api.inject.guice.GuiceInjectorBuilder
import play.api.inject.{ApplicationLifecycle, DefaultApplicationLifecycle, Injector, bind}
import scala.concurrent.ExecutionContext
class WorkingModule extends AbstractModule with ScalaModule {
override def configure(): Unit =
bind[CustomTFInterface[IO]].toInstance(new CustomTFInterfaceImpl)
}
class HomeControllerSpec extends AnyFlatSpec with Matchers {
it should "test1" in {
val application: Injector = new GuiceInjectorBuilder()
.bindings(bind[ExecutionContext].to(ExecutionContext.global))
.bindings(bind[ApplicationLifecycle].to[DefaultApplicationLifecycle])
.bindings(bind[CustomTFInterface[IO]].toInstance(new CustomTFInterfaceImpl))
.bindings(new CatsEffectModule())
.injector()
application.instanceOf[CustomTFInterface[IO]] // works
//application.instanceOf[InjecableWithTfDependencies] // fails
}
it should "test2" in {
val application: Injector = new GuiceInjectorBuilder()
.bindings(bind[ExecutionContext].to(ExecutionContext.global))
.bindings(bind[ApplicationLifecycle].to[DefaultApplicationLifecycle])
.bindings(new WorkingModule())
.bindings(new CatsEffectModule())
.injector()
//application.instanceOf[CustomTFInterface[IO]] // fails
application.instanceOf[InjecableWithTfDependencies] // works
}
it should "test3" in {
val application: Injector = new GuiceInjectorBuilder()
.bindings(bind[ExecutionContext].to(ExecutionContext.global))
.bindings(bind[ApplicationLifecycle].to[DefaultApplicationLifecycle])
// both binds together also works
.bindings(new WorkingModule())
.bindings(bind[CustomTFInterface[IO]].toInstance(new CustomTFInterfaceImpl))
.bindings(new CatsEffectModule())
.injector()
application.instanceOf[CustomTFInterface[IO]]       // works
application.instanceOf[InjecableWithTfDependencies] // works
}
}

也许有一种方法可以让scala guide和play一起工作,但我运气不好。

完整示例:https://github.com/DenisNovac/play-tf-test

相关内容

  • 没有找到相关文章

最新更新