gpt4 book ai didi

scala - 如何使用 Scala Guice 绑定(bind)一个扩展具有 monadic 类型参数的 Trait 的类?

转载 作者:行者123 更新时间:2023-12-02 00:17:05 25 4
gpt4 key购买 nike

我需要绑定(bind)这个特性的实现:

trait ClientRepository[F[_]] {
def list(): F[Iterable[ClientDTO]]
}

对于这个实现:

import cats.effect.IO

@Singleton
class ClientRepositoryImpl @Inject()(db: OldDataBase, c: IOContextShift)
extends ClientRepository[IO] {

override def list(): IO[Iterable[ClientDTO]] = ???
}

我正在使用 Scala Play! v2.7.2 和 Scala v2.12.8,以及 scala-guice v4.2.1。为了将特性绑定(bind)到它的实现,我想在我的 Module.scala 中做类似的事情:

class Module(environment: Environment, configuration: Configuration)
extends AbstractModule
with ScalaModule {

override def configure() = {

bind[ClientRepository].to[ClientRepositoryImpl[IO]].in[Singleton]

}
}

我得到的错误是:

[error] app/Module.scala:37:9: kinds of the type arguments (ClientRepository) do not conform to the expected kinds of the type parameters (type T).
[error] ClientRepository's type parameters do not match type T's expected parameters:
[error] trait ClientRepository has one type parameter, but type T has none
[error] bind[ClientRepository].to[ClientRepositoryImpl[IO]].in[Singleton]
[error] ^
[error] app/Module.scala:37:31: ClientRepositoryImpl does not take type parameters
[error] bind[ClientRepository].to[ClientRepositoryImpl[IO]].in[Singleton]
[error] ^
[error]

我也试过:

绑定(bind)[ClientRepository[IO]].to[ClientRepositoryImpl].in[Singleton]

Module.scala:37:9: kinds of the type arguments (cats.effect.IO) do not conform to the expected kinds of the type parameters (type T).
[error] cats.effect.IO's type parameters do not match type T's expected parameters:
[error] class IO has one type parameter, but type T has none
[error] bind[ClientRepository[IO]].to[ClientRepositoryImpl].in[Singleton]
[error] ^

绑定(bind)[ClientRepository[IO[_]]].to[ClientRepositoryImpl].in[Singleton]

Module.scala:37:27: cats.effect.IO[_] takes no type parameters, expected: one
[error] bind[ClientRepository[IO[_]]].to[ClientRepositoryImpl].in[Singleton]
[error] ^

解决此问题的正确方法是什么?

最佳答案

我使用 Guice 的 TypeLiteral 找到了正确的解决方案,看完this SO answerthis one .

工作解决方案是:

    // In Module.scala configure()
bind(new TypeLiteral[ClientRepository[IO]] {}).to(classOf[ClientRepositoryImpl])

因为我们必须提供一个可以实例化的类(带有类型参数,在我们的例子中是 IO )。 TypeLiteral ,这是一个特殊的类,使您能够指定完整的参数化类型,可用于创建与我们 Repo[F[_]] 的特定实现的实际绑定(bind)。 .无法实例化具有通用参数的类,但我们可以强制 Guice 选择特定的 ClientRepository已使用类型参数 cats.effect.IO 构造.

最后但并非最不重要的一点是,每当您必须注入(inject)特征时 ClientRepository您还必须指定类型参数。例如:

class ClientResourceHandler @Inject()(
routerProvider: Provider[ClientRouter],
clientRepository: ClientRepository[IO]
)

ClientResourceHandler需要调用 repo,所以我们使用特征 ClientRepository[IO] 注入(inject)它(不只是 ClientRepository )。

关于scala - 如何使用 Scala Guice 绑定(bind)一个扩展具有 monadic 类型参数的 Trait 的类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56668719/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com