我正在寻找一种在Scala中进行依赖注入的方式,如Spring中的Spring或Unity,我发现没有什么真正有趣的。
所以我决定让我的实施并问你的想法是什么,因为令我惊讶的是,之前没有做过这样的事情。也许我的实现在现实生活中也有很多问题。
所以这是一个例子:
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
}
}
总结:
您怎么看?
答案 0 :(得分:2)
您的代码看起来很像Lift Web框架中的依赖注入。您可以查阅Lift源代码以了解它是如何实现的,或者只是使用框架。您无需运行Lift应用程序即可使用其库。这是一个小介绍doc。基本上你应该在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 - write unit tests for objects/singletons that extends a trait/class with DB connection,其中显示了如何使用Lift进样器。
答案 1 :(得分:0)
谢谢你们,
所以我做出了答案,但是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不喜欢的是各地的暗示。我知道有一种方法可以避免它们,但它看起来像是对我的修复。
由于
答案 2 :(得分:0)
要评论MacWire,你是对的,你可以使用new
- 这就是重点:)。 MacWire只允许您从代码中删除一些样板,而不必再次枚举所有依赖项(已在构造函数中完成)。
主要的想法是你在“世界末日”进行布线,在那里组装你的应用程序(或者你可以把它分成特征模块,但这是可选的)。否则,您只需使用构造函数来表示依赖关系。没有魔法,没有框架。