簡體   English   中英

使用Scala進行依賴注入

[英]Dependency injection with Scala

我正在尋找一種在Scala中進行依賴注入的方式,比如Spring中的Spring或Unity,我發現沒有什么真正有趣的。

  • MacWire:我不明白這個好處,因為我們必須給線上課[CASS]。 那么,如果在調用wire時給出實現,那又有什么意義呢? 我可以做新的CASS它會是一樣的。
  • 自我類型的蛋糕模式:似乎沒有回答我正在尋找的東西。

所以我決定進行實施,然后問你的想法是什么,因為令我驚訝的是之前沒有做過這樣的事情。 也許我的實現在現實生活中也有很多問題。

所以這是一個例子:

trait Messenger {
  def send
}

class SkypeMessenger extends Messenger {
  def send = println("Skype")
}

class ViberMessenger extends Messenger {
  def send = println("Viber")
}

我想在我的應用程序中隨處注入僅在一個地方配置的實現:

object App {
  val messenger = Inject[Messenger]

  def main(args: Array[String]) {
    messenger.send
  }
}

注意我使用我想要的配置(prod或dev)定義的Inject [Messenger]如下所示:

object Inject extends Injector with DevConfig

trait ProdConfig {
  this: Injector =>
  register[Messager](new SkypeMessager)
  register[Messager](new ViberMessager, "viber")
}

trait DevConfig {
  this: Injector =>
  register[Messager](new ViberMessager)
  register[Messager](new ViberMessager, "viber")
}

最后這里是包含所有方法的Injector並注冊:

class Injector {
  var map = Map[String, Any]()

  def apply[T: ClassTag] =
    map(classTag[T].toString).asInstanceOf[T]

  def apply[T: ClassTag](id: String) =
    map(classTag[T].toString + id).asInstanceOf[T]

  def register[T: ClassTag](instance: T, id: String = "") = {
    map += (classTag[T].toString + id -> instance)
    instance
  }
}

總結:

  • 我有一個類Injector,它是接口/ traits之間的Map(最終也是id)和實現的實例。
  • 我們為包含寄存器的每個配置(dev,prod ...)定義一個特征。 它還有一個Injector的自我參考。
  • 我們用我們想要的Config創建一個Injector實例
  • 用法是調用apply方法給出Interface類型(最終也是id),它將返回實現的實例。

你怎么看?

您的代碼看起來很像Lift Web框架中的依賴注入。 您可以查閱Lift源代碼以了解它是如何實現的,或者只是使用框架。 您無需運行Lift應用程序即可使用其庫。 這是一個小型的介紹文檔 基本上你應該在Lift中查看這段代碼:

package net.liftweb.http

/**
 * A base trait for a Factory.  A Factory is both an Injector and
 * a collection of FactorMaker instances.  The FactoryMaker instances auto-register
 * with the Injector.  This provides both concrete Maker/Vender functionality as
 * well as Injector functionality.
 */
trait Factory extends SimpleInjector

您還可以檢查以下相關問題: Scala - 使用DB連接擴展特征/類的對象/單例的單元測試,其中顯示了如何使用Lift注入器。

多謝你們,

所以我做出了答案,但是Aleksey的答案非常好。

我更了解這個樣本的蛋糕模式:
https://github.com/freekh/play-slick/tree/master/samples/play-slick-cake-sample
看看沒有DI的其他實現並比較:
https://github.com/freekh/play-slick/tree/master/samples/

所以蛋糕模式沒有像我們所展示的升降式DI那樣的集中配置。 無論如何,我會使用Cake模式,因為它非常適合Slick。
我對Subcut不喜歡的是各地的暗示。 我知道有一種方法可以避免它們,但它看起來像是對我的修復。

謝謝

要評論MacWire ,你是對的,你可以使用new - 這就是重點:)。 MacWire只允許您從代碼中刪除一些樣板,而不必再次枚舉所有依賴項(已在構造函數中完成)。

主要的想法是你在“世界末日”進行布線,在那里組裝你的應用程序(或者你可以把它分成特征模塊,但這是可選的)。 否則,您只需使用構造函數來表示依賴關系。 沒有魔法,沒有框架。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM