2017-01-04 108 views
0

我在理解依赖注入的基本思想方面有点麻烦。 (我使用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(" ")) 
) 

} 

我假设我误解了依赖注入应该如何工作。

所以我的问题如下:

  1. 什么在我的模型Users使用@Inject()关键字,然后点?

  2. 我的设计模式有瑕疵吗?我很乐意将UsersUserSearch作为对象,但之后我无法在它们上使用依赖注入。

  3. 如果有人对Slick很熟悉,那么我的getAll()方法是否适用于光滑?这甚至是编写异步代码的正确方法吗?

+0

'UserSearch'应该注入'Users',而不是'Users'需要的'DatabaseConfigProvider'。没有理由'UserSearch'需要知道这一点。 –

+0

@MichaelZajac谢谢,但是我会每次在控制器的Action方法中创建'new Users'的实例吗? – rusins

+0

不,DI框架应该为您创建所有的依赖关系。如果你需要在你的控制器中使用'Users',它应该被注入你的控制器。 –

回答

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错误,但至少我的项目编译。后来我想出了第三个问题 - 事实证明,没有理由创建表格方案,因为在我的情况下,它是通过播放evolutions文件完成的,因此我删除了setupFuture.flatMap部分,尽管它可以正常工作,并且不会不要做任何愚蠢的事情,比如创建表格两次,或者在创建/启动表格时需要做的任何事情。

0

的DI的优势之一,就是用其他的实现,在测试中特别有用,您可以在参数传递一个模拟的难易程度。

举例来说,如果你收到一个类(MyExternalClass),将调用外部API的情况下,可以改为发送一个子类(MyExternalSubClass extends MyExternalClass),将覆盖调用API的方法,并简单地返回一个预配置的JSON

还有这里列出几个优点(和缺点)(网络上的许多其他有趣的文章):

+0

为什么没有依赖注入工作呢? – rusins

相关问题