实例化给定@inject类的val

时间:2016-01-18 18:27:06

标签: scala playframework reactivemongo play-reactivemongo

如何从此类实例化对象?我有另一个类,我想使用下面定义的MongoUtils类。此课程来自reactivemongo

package controllers

import javax.inject.Inject

import scala.concurrent.Future

import play.api.Logger
import play.api.mvc.{ Action, Controller }
import play.api.libs.concurrent.Execution.Implicits.defaultContext
import play.api.libs.functional.syntax._
import play.api.libs.json._

// Reactive Mongo imports
import reactivemongo.api.Cursor

import play.modules.reactivemongo.{ // ReactiveMongo Play2 plugin
MongoController,
ReactiveMongoApi,
ReactiveMongoComponents
}

// BSON-JSON conversions/collection
import reactivemongo.play.json._
import play.modules.reactivemongo.json.collection._

/*
 * Example using ReactiveMongo + Play JSON library.
 *
 * There are two approaches demonstrated in this controller:
 * - using JsObjects directly
 * - using case classes that can be turned into JSON using Reads and Writes.
 *
 * This controller uses JsObjects directly.
 *
 * Instead of using the default Collection implementation (which interacts with
 * BSON structures + BSONReader/BSONWriter), we use a specialized
 * implementation that works with JsObject + Reads/Writes.
 *
 * Of course, you can still use the default Collection implementation
 * (BSONCollection.) See ReactiveMongo examples to learn how to use it.
 */
class MongoUtils @Inject() (val reactiveMongoApi: ReactiveMongoApi)
  extends Controller with MongoController with ReactiveMongoComponents {

  /*
   * Get a JSONCollection (a Collection implementation that is designed to work
   * with JsObject, Reads and Writes.)
   * Note that the `collection` is not a `val`, but a `def`. We do _not_ store
   * the collection reference to avoid potential problems in development with
   * Play hot-reloading.
   */
  def collection: JSONCollection = db.collection[JSONCollection]("persons")

  def index = Action { Ok("works") }

  def create(name: String, age: Int) = Action.async {
    val json = Json.obj(
      "name" -> name,
      "age" -> age,
      "created" -> new java.util.Date().getTime())

    collection.insert(json).map(lastError =>
      Ok("Mongo LastError: %s".format(lastError)))
  }

  def createFromJson = Action.async(parse.json) { request =>
    import play.api.libs.json.Reads._
    /*
     * request.body is a JsValue.
     * There is an implicit Writes that turns this JsValue as a JsObject,
     * so you can call insert() with this JsValue.
     * (insert() takes a JsObject as parameter, or anything that can be
     * turned into a JsObject using a Writes.)
     */
    val transformer: Reads[JsObject] =
      Reads.jsPickBranch[JsString](__ \ "firstName") and
        Reads.jsPickBranch[JsString](__ \ "lastName") and
        Reads.jsPickBranch[JsNumber](__ \ "age") reduce

    request.body.transform(transformer).map { result =>
      collection.insert(result).map { lastError =>
        Logger.debug(s"Successfully inserted with LastError: $lastError")
        Created
      }
    }.getOrElse(Future.successful(BadRequest("invalid json")))
  }

  def findByName(name: String) = Action.async {
    // let's do our query
    val cursor: Cursor[JsObject] = collection.
      // find all people with name `name`
      find(Json.obj("name" -> name)).
      // sort them by creation date
      sort(Json.obj("created" -> -1)).
      // perform the query and get a cursor of JsObject
      cursor[JsObject]()

    // gather all the JsObjects in a list
    val futurePersonsList: Future[List[JsObject]] = cursor.collect[List]()

    // transform the list into a JsArray
    val futurePersonsJsonArray: Future[JsArray] =
      futurePersonsList.map { persons => Json.arr(persons) }

    // everything's ok! Let's reply with the array
    futurePersonsJsonArray.map { persons =>
      Ok(persons)
    }
  }
}

到目前为止,我已经尝试了val mongoutil = new MongoUtils(reactiveMongoApi = play.modules.reactivemongo) ,但显然它不起作用。

2 个答案:

答案 0 :(得分:0)

如果您在控制器中使用此类,则应按如下方式注释控制器,以便在其中注入实例:

class MyController @Inject() (mongoUtils: MongoUtils) extends Controller {}

如果您没有使用注入的控制器,可以通过注射器访问它:

Play.current.injector.instanceOf(classOf[MongoUtils])

在此处阅读有关依赖注入的更多信息:https://www.playframework.com/documentation/2.4.x/ScalaDependencyInjection

答案 1 :(得分:0)

您可以使用Play的依赖注入机制来解析ReactiveMongoApi的实例,它是MongoDB的接口。步骤可以是:

将以下行添加到application.conf

play.modules.enabled += "play.modules.reactivemongo.ReactiveMongoModule"
play.modules.enabled += "modules.CommonModule"

modules.CommonModule 是您定义绑定的位置,因此与Play 2.4集成的DI框架Guice知道要用于特定接口的实现。例如,

package modules

import com.google.inject.AbstractModule
import dao.impl.UserDaoMongo
import dao.UserDao
import play.api.{Configuration, Environment}
import services.{UserService, UserServiceImpl}
case class CommonModule(environment: Environment, configuration: Configuration) extends AbstractModule {

  def configure() {
    bindDAOs()
    bindServices()
  }

  private def bindDAOs(): Unit = {
    bind(classOf[UserDao]).to(classOf[UserDaoMongo])
  }

  def bindServices(): Unit = {
    bind(classOf[UserService]).to(classOf[UserServiceImpl])
  }
}

此外,将控制器设为单身是一个好习惯。例如:

import javax.inject.{Singleton, Inject}

@Singleton    
class UserController @Inject()(userService: UserService) extends Controller {

请阅读此内容以了解如何在Play框架中使用Reactivemongo。另一方面,这是一个完整的例子:https://github.com/luongbalinh/play-mongo