我在理解依赖注入的基本思想时遇到了一些麻烦。 (我正在使用Play 2.5与play-slick模块)说我有一个需要数据库连接的类Users
。
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
}
当我有一个需要访问这些方法的视图时,我希望依赖注入系统为我填写dbConfigProvider
依赖关系,就像这样。
package views
class UserSearch {
def index(implicit ec: ExecutionContext): Future[String] = Future(
(new Users).getAll().map(seq => seq.map(user => user.name).mkString(" "))
)
}
然而,这给了我一个编译错误,我被迫使dbConfigProvider
依赖于我的视图并明确地传递它。在这种情况下,我终于从调用该视图的控制器获取dbConfigProvider
。
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(" "))
)
}
我假设我误解了依赖注入应该如何工作。
所以我的问题如下:
在我的模型@Inject()
中使用Users
关键字的重点是什么?
我的设计模式有缺陷吗?我希望Users
和UserSearch
成为对象,但我不能在它们上使用依赖注入。
如果有人熟悉Slick,我的getAll()
方法是使用光滑的方法吗?这甚至是编写异步代码的正确方法吗?
答案 0 :(得分:0)
例如,如果您收到将调用外部API的类(MyExternalClass
)的实例,则可以发送一个子类(MyExternalSubClass extends MyExternalClass
)来覆盖调用API的方法,并简单地返回一个预先配置的json
此处列出了一些优点(和缺点)(网上还有许多其他有趣的文章):
答案 1 :(得分:0)
感谢@MichaelZajac的评论,我将UserSearch
改为声明为:
class UserSearch @Inject (users: Users)
现在我的控制器设置如下:
class UsersController @Inject()(userSearch: UserSearch) extends Controller {
def index = Action.async {
implicit request => userSearch.index().map(Ok(_))
}
}
这直接回答了我的第一个问题,看到这个问题也回答了我的第二个问题。我现在收到SQL错误,但至少我的项目编译。我后来想出了我的第三个问题 - 结果是没有理由创建表格方案,因为在我的情况下它是由play evolutions文件完成的,因此我删除了setupFuture.flatMap
部分,即使它可以正常工作它,并没有做任何愚蠢的事情,如创建表两次,或者在创建/启动表时可能需要做的其他事情。