如何依赖注入Play 2.5中的数据库

时间:2016-11-13 16:25:44

标签: scala playframework dependency-injection playframework-2.5

我从游戏2.3迁移到2.5

最初我有" DAOFactory"对象

object DAOFactory {
  def categoryDAO: CategoryDAO =  AnormCategoryDAO

  def itemDAO: ItemDAO = AnormItemDAO

  def bidDAO: BidDAO = AnormBidDAO

  def userDAO: UserDAO = AnormUserDAO

  def feedStatsDAO: FeedStatsDAO = AnormFeedStatsDAO
}

让我们采取" AnormCategoryDAO"作为一个例子,我必须改变"对象"进入"班级"

object AnormCategoryDAO extends CategoryDAO {
  val category = {
    int("id") ~ str("display_name") ~ str("url_name") map {
      case id~displayName~urlName => Category(id, displayName, urlName)
    }
  }

  def create(displayName: String, urlName: String) = DB.withConnection { implicit c =>
    SQL("INSERT INTO category(display_name, url_name) VALUES({displayName}, {urlName})").on(
      'displayName -> displayName, 'urlName -> urlName).executeUpdate()
  }

  def findById(id: Int): Option[Category] = DB.withConnection { implicit c =>
    SQL("SELECT * FROM category WHERE id = {id}").on('id -> id).as(category singleOpt)
  }

  def findByName(urlName: String): Option[Category] = DB.withConnection { implicit c =>
    SQL("SELECT * FROM category WHERE url_name = {urlName}").on('urlName -> urlName).as(category singleOpt)
  }

  def all(): List[Category] = DB.withConnection { implicit c =>
    SQL("SELECT * FROM category ORDER BY display_name").as(category *)
  }
}

所以我将OBJECT改为CLASS并用SINGLETON注释如下,我改变了#34; DB.withConnection" to" db.withConnection"

@Singleton
class AnormCategoryDAO @Inject()(db: Database) extends CategoryDAO {
  val category = {
    int("id") ~ str("display_name") ~ str("url_name") map {
      case id~displayName~urlName => Category(id, displayName, urlName)
    }
  }

...

现在," AnormCategoryDAO"是一个班级。所以我需要弄清楚用默认数据库实例化它的方法。 但我不知道如何实例化它。

object DAOFactory {
  //def categoryDAO: CategoryDAO = AnormCategoryDAO

  def userDAO: UserDAO = AnormUserDAO

  def itemDAO: ItemDAO = AnormItemDAO
}

问题是,如何注入数据库并实例化它?

2 个答案:

答案 0 :(得分:0)

我不喜欢使用guice或类似di。使用编译时间di我可以通过使用类似的东西来实现:

import play.api.db.slick.{DbName, SlickComponents}

trait TablesComponents extends BaseComponent with SlickComponents {

  lazy val dbConf = api.dbConfig[JdbcProfile](DbName("default"))

  lazy val myTable = new MyTable(dbConf.db)
  lazy val otherTable = new OtherTable(dbConf.db)
}

答案 1 :(得分:0)

您要么已准备好要注入的依赖项,在这种情况下,您可以直接调用new AnormCategoryDAO(myDb),或者在需要的任何地方注入AnormCategoryDAO(这可能意味着依赖项注入会传播所有到控制器的方式,由Play实例化。

例如:

class CategoryService @Inject() (categoryDao: CategoryDAO) {
  def findAll() = categoryDao.findAll()
}

请注意,在此示例中,我使用抽象类型CategoryDAO来引用categoryDAO。为此,你必须告诉依赖注入框架(通常是Guice),它构造了它应该注入的类(绑定)。或者,您可以直接依赖AnormCategoryDAO

此处记录了如何定义自定义绑定:https://www.playframework.com/documentation/2.5.x/ScalaDependencyInjection

请注意,存在一种名为编译时间的依赖注入的替代方法:https://www.playframework.com/documentation/2.5.x/ScalaCompileTimeDependencyInjection