在scala main中将对象注入App中

时间:2017-03-08 16:16:20

标签: scala dependency-injection guice

以下是代码:

import akka.actor.ActorSystem
import akka.stream.ActorMaterializer
import akka.stream.scaladsl.Sink
import com.google.inject.Inject
import org.bytedeco.javacv.{CanvasFrame, Frame}

class WebCamWindow @Inject()(webCam: WebCam) {

  implicit val system = ActorSystem()
  implicit val materializer = ActorMaterializer()

  val canvas = new CanvasFrame("Webcam")
  //  Set Canvas frame to close on exit
  canvas.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE)

  val imageDimensions = Dimensions(width = 640, height = 480)
  val webcamSource = webCam.source

  val graph = webcamSource
    .map(MediaConversion.toMat) // most OpenCV manipulations require a Matrix
    .map(Flip.horizontal)
    .map(MediaConversion.toFrame) // convert back to a frame
    .map(canvas.showImage)
    .to(Sink.ignore)

  def run(): Unit = {
    graph.run()
  }
}

我想把它作为一个App对象并运行它,但我不知道如何在这里处理依赖注入。有人可以帮忙吗?

可在此处找到完整项目:https://bitbucket.org/kindlychung/testscalacv

1 个答案:

答案 0 :(得分:1)

第一步是将其变成特征(仅为方便起见):

trait WebCamWindowLike  {
   def webCam: WebCam

   implicit val system ...//all the code is here

}

然后你可以使用旧的注射剂WebCamWindow

class WebCamWindow @Inject()(val webCam: WebCam) extends WebCamWindowLike

以及独立的runnable对象:

object WebCamWindowApp extends App with WebCamWindowLike {
   private val injector = Guice.createInjector(new AppInjectory())
   override val webCam = injector.getInstance(classOf[WebCam])
   run()
}

AppInjectory extends AbstractModule是Guice的实际注入,负责处理所有依赖项。

另一种选择是(如果你想摆脱Guice)手动“注射”:

object WebCamWindowApp extends App with WebCamWindowLike {

   override val webCam = new WebCam(...)
   run()

}