【发布时间】:2014-03-25 00:30:55
【问题描述】:
我正在寻找一种在 Scala 中进行依赖注入的方法,有点像 C# 中的 Spring 或 Unity,但我没有发现任何真正有趣的东西。
- MacWire:我不明白这样做的好处,因为我们必须在 Wire[CASS] 中提供课程。那么,如果您在调用电汇时给出实现,那有什么意义呢?我可以做新的 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
}
}
注意我在下面定义的 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,它包含了所有的方法 apply 和 register:
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,它是接口/特征(最终也是一个 id)和实现实例之间的映射。
- 我们为每个包含寄存器的配置(开发、产品...)定义了一个特征。它还具有对 Injector 的自我引用。
- 然后我们使用我们想要的配置创建一个 Injector 实例
- 用法是调用apply方法给出接口类型(最终也是一个id),它将返回实现的实例。
你怎么看?
【问题讨论】:
-
我认为,如果您提供一个示例,说明为什么现有方法在应用于您的用例时存在缺陷,这将对我有所帮助。这个问题太抽象了,我现在无法给出反馈。
-
您的实现将如何解决内部依赖关系并不明显。还可以看看
subcut,它(几乎)拥有 scala 中运行时 DI 所需的一切。
标签: scala dependency-injection