I'm having a bit of trouble understanding the basic idea of dependency injection. (I'm using Play 2.5 with the play-slick module) Say I have a class Users
that needs a database connection.
package models
@Singleton
class Users @Inject() (dbConfigProvider: DatabaseConfigProvider) {
private val db = dbConfigProvider.get[JdbcProfile].db
private val users = TableQuery[UserTable]
private val setupAction = DBIO.seq(users.schema.create)
private val setupFuture: Future[Unit] = db.run(setupAction)
def getAll(): Future[Seq[User]] = setupFuture.flatMap(_ =>
db.run(users.result)
)
// More methods like the previous
}
When I have a view that needs to access these methods, I would expect the dependency injection system to fill out dbConfigProvider
dependency for me, like this.
package views
class UserSearch {
def index(implicit ec: ExecutionContext): Future[String] = Future(
(new Users).getAll().map(seq => seq.map(user => user.name).mkString(" "))
)
}
However this gives me a compilation error and I am forced to make dbConfigProvider
a dependency of my view and pass it in explicitly. In this case I finally get the dbConfigProvider
from a controller calling the view.
package views
class UserSearch @Inject (dbConfigProvider: DatabaseConfigProvider) {
def index(implicit ec: ExecutionContext): Future[String] = Future(
(new Users(dbConfigProvider)).getAll().map(seq =>
seq.map(user => user.name).mkString(" "))
)
}
I'm assuming I've misunderstood how dependency injection should work.
So my questions are as follows:
What's the point of using the
@Inject()
keyword in my modelUsers
then?Is my design patter flawed? I would love to have
Users
andUserSearch
be objects, but then I can't use dependency injection on them.In case anyone is familiar with Slick, is my
getAll()
method the propper way to be working with slick? Is this even the correct way to write asynchronous code?