Scala依赖项注入,用于编译时的独立配置

Scala依赖项注入,用于编译时的独立配置,scala,symfony,dependency-injection,Scala,Symfony,Dependency Injection,现在我首先意识到这个标题非常广泛,所以让我来描述一下这个用例 背景: 我目前正在自学Scala+Gradle(因为我喜欢Gradle的灵活性和功能,以及更清晰的构建文件) 因此,学习新的语言通常是最好的,以使您能够实际使用的应用程序,并且主要是一名PHP(使用Symfony)程序员和以前的Java程序员,有许多模式可以从这两种范式中继承 用例: 我正在编写一个应用程序,其中我正在试验Provider+接口(trait)布局,目标是定义包含任何特定类型组件的所有预期功能的trait,例如作为提供者

现在我首先意识到这个标题非常广泛,所以让我来描述一下这个用例

背景: 我目前正在自学Scala+Gradle(因为我喜欢Gradle的灵活性和功能,以及更清晰的构建文件)

因此,学习新的语言通常是最好的,以使您能够实际使用的应用程序,并且主要是一名PHP(使用Symfony)程序员和以前的Java程序员,有许多模式可以从这两种范式中继承

用例: 我正在编写一个应用程序,其中我正在试验Provider+接口(trait)布局,目标是定义包含任何特定类型组件的所有预期功能的trait,例如作为提供者的
ConfigReaderTrait
YamlConfigManager
。从理论上讲,这样做的好处是允许我以最小的努力切换出核心机制甚至架构组件,这允许大量的研发和实验

PHP符号影响 现在,我作为一名纯PHP开发人员工作,因此已经介绍给Symfony,它有一个出色的依赖项注入框架,其中依赖项在yaml文件中定义,并且可以委托给子目录。我喜欢这一点,因为与SBT不同,我不分阶段地使用不同的语言用于不同的目的(例如groovy和gradle用于构建脚本),我希望保持关注点的分离

这样,每种类型的接口/特征或相关功能包都应该能够有自己的DI配置,我更希望它与scala代码本身分开

现在是Scala。。。。 很明显,不同语言之间的情况并不相同,如果你不接受这些差异,你也可以回到以前的语言,把事情留在那里

也就是说,我还不相信scala的DI框架

  • 例如,Guice实际上是一个经过修改的java框架(这很好) 因为scala可以使用Javalibs,但是因为它们不在 感觉就像是编码语言的完全相同的范例 scala的功能未得到充分利用)
  • MacWire让我有点恼火,因为您必须定义依赖项 在您使用它们的文件中。这对我的工作没有帮助 接口/提供者概念
  • 到目前为止,SubCut似乎最符合我的期望
但是,尽管经历了所有这些(请记住,这都是在研究阶段,我还没有使用过任何一个),Scala中的DI似乎仍然非常分散,在其初期,我的意思是,不同的应用程序有不同的实现,但没有一个足够灵活或强大到可以与Symfonys DI相比。尤其是我的申请

评论?想法?

我的5美分:

在从Java切换到Scala之后,我实际上已经停止使用依赖注入框架

该语言允许在没有框架的情况下使用一些很好的方法(多参数列表和咖喱,以及像“蛋糕模式”那样进行注入的混合) 我发现自己越来越只使用基于构造函数或方法参数的注入,因为它清楚地记录了给定逻辑段的依赖关系以及这些依赖关系来自何处

使用Scala
object
s为实现创建不同的模块集或工厂,然后在运行时在这些模块集或工厂之间进行选择,这也相当容易。这将保证除非有可用的实现,否则它不会编译,而Java land中的大型实现会在运行时失败,从而有效地将编译时问题推到运行时

这也消除了如何创建和连接依赖项的“魔力”(反射、运行时编织、宏、XML、将上下文绑定到线程本地等)。我认为这使新开发人员更容易进入项目并理解代码库是如何相互关联的


关于用非代码(如XML)声明实现,我发现项目很少或永远不会在不发布新版本的情况下更改这些文件,因此它们也可能是代码,具有所有带来的好处(IDE支持、性能、类型检查)。

感谢您的回答,它提供了一个不同的视角。我主要想解决的问题是接口提供者。以您描述的方式使用工厂可以解决这个问题。我不关心部署,只关心从使用中抽象出
提供程序
,通过使用
工厂
,我可以返回一个初始化的对象,并且只在一个位置声明使用了哪个
提供程序
。在相关组件中声明提供程序,而不是删除声明并将其放在其他地方,这也很好。在这种情况下,由于模式有点晚,实际上我并不感到困扰,但出于好奇,你说使用MacWire时,你必须在使用它们的文件中定义DEP是什么意思?MacWire只能在“世界末日”使用,在“世界末日”中,您可以实际组装应用程序(或者您可以使用traits将其分解为模块),否则您可以自由使用traits(接口)。