带有 Play2.4 和 scala 的 Google Guice 的循环依赖错误

Posted

技术标签:

【中文标题】带有 Play2.4 和 scala 的 Google Guice 的循环依赖错误【英文标题】:Circular Dependency Error for Google Guice with Play2.4 and scala 【发布时间】:2015-06-30 13:33:33 【问题描述】:

我的应用程序使用 Play 2.4 和 Scala 2.11。我开始转换现有代码以使用 Play 2.4 附带的 Google Guice

在进行第一组更改后运行我的代码时,我发现我的代码中的一些 DAO 因 循环依赖错误而失败。

例如我有两个 DAO

class BookDAO @Inject()
(protected val personDAO : PersonDAO,
 @NamedDatabase("mysql")protected val dbConfigProvider: DatabaseConfigProvider) extends HasDatabaseConfigProvider[JdbcProfile] 
...
...
val personId = //some id
personDAO.get(personId)


class PersonDAO @Inject()
(protected val bookDAO : BookDAO,
 @NamedDatabase("mysql")protected val dbConfigProvider: DatabaseConfigProvider) extends HasDatabaseConfigProvider[JdbcProfile] 
...
...
val bookName= //some id
personDAO.getByName(bookName)

我在尝试访问 BookDAO 或 PersonDAO 时遇到以下错误

Tried proxying schema.BookDAO to support a circular dependency, but it is not an interface.
  at schema.BookDAO.class(Books.scala:52)
  while locating schema.BookDAO

谁能帮我解决这个错误。

提前致谢

【问题讨论】:

【参考方案1】:

快速解决方案

改为注入Provider

class BookDAO @Inject()(personDaoProvider: Provider[PersonDAO], ...)
extends HasDatabaseConfigProvider[JdbcProfile] 
  val personDAO = personDaoProvider.get
  def person = personDAO.get(personId)

BookDAO 也是如此。这将开箱即用。 Guice 已经“知道”如何注入 Providers。


更好的方法

将类定义与实现分离。请参阅 Mon Calamari 的回答。

【讨论】:

【参考方案2】:

如下定义你的依赖,并从类中提取所有需要的方法到特征:

@ImplementedBy(classOf[BookDao])
trait IBookDao 
  // abstract defs


class BookDao @Inject()(protected val personDAO: IPersonDao, protected val dbConfigProvider: DatabaseConfigProvider) extends HasDatabaseConfigProvider[JdbcProfile] with IBookDao 


@ImplementedBy(classOf[PersonDao])
trait IPersonDao 
  // abstract defs


class PersonDao @Inject()(protected val bookDAO: IBookDao, protected val dbConfigProvider: DatabaseConfigProvider) extends HasDatabaseConfigProvider[JdbcProfile] with IPersonDao 

如您所见,每个dao 都实现了一个特征,所有dao 依赖项都由trait 注入。这使Guice 可以注入代理类并解决循环依赖问题。

更多关于playframework scala依赖注入here的细节。

【讨论】:

以上是关于带有 Play2.4 和 scala 的 Google Guice 的循环依赖错误的主要内容,如果未能解决你的问题,请参考以下文章

Scala:编译错误:方法重载

Play 2.4 中的 Global.getControllerInstance 等价物是啥?

如何在 play 2.4 中的 scala 模板中设置类型列表字段的值?

Scala Play Framework,在哪里创建演员?

scala.MatchError:某个时间点之后的所有请求都为空

玩 2.4 参数化代数数据类型 JSON 验证