My application uses Play 2.4 with Scala 2.11 .I started transforming my existing code to make use of Google Guice that comes with Play 2.4 .
When I run my code after making the first set of changes , I found Some DAOs in my code are failing with circular dependency error.
For example I have two DAOs
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)
}
I got the below error while trying to access either BookDAO or 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
Can someone help me resolving this error .
Thanks in advance
Inject a Provider
instead:
class BookDAO @Inject()(personDaoProvider: Provider[PersonDAO], ...)
extends HasDatabaseConfigProvider[JdbcProfile] {
val personDAO = personDaoProvider.get
def person = personDAO.get(personId)
}
And the same for BookDAO
. This will work out of the box. Guice already "knows" how to inject Providers.
Decouple the class definition from the implementation. See Mon Calamari's answer.
Define your dependencies as follows and pull up all needed methods from class to trait:
@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 {
}
As you can see, each dao
implements a trait and all dao
dependencies are injected by trait
. This gives Guice
possibility to inject a proxy class and resolve a circular dependency issue.
More details on playframework scala
dependency injection here .
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.