5

我的应用程序使用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

有人可以帮我解决这个错误。

提前致谢

4

2 回答 2

4

快速解决方案

Provider而是注入一个:

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

对于BookDAO. 这将开箱即用。Guice 已经“知道”如何注入 Providers。


更好的方法

将类定义与实现分离。见蒙卡拉马里的回答。

于 2015-06-30T13:59:01.623 回答
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依赖注入的细节在这里

于 2015-06-30T13:51:24.840 回答