比较Subcut和Scaldi

时间:2013-05-20 09:36:49

标签: scala configuration dependency-injection subcut scaldi

我正在查看 SubCut Scaldi 以在我的项目中使用。各自入门文档中提供的示例似乎非常相似。这两个项目似乎都没有提供入门和scala文档之外的文档。

有人可以总结这些框架之间的实际差异,主要是在功能和成熟度/稳定性方面。我正在研究这些包,因为我需要能够在运行时动态创建和组合配置。运行时配置是我查看这些库而不是使用implicits和/或层蛋糕模式进行DI /配置的主要原因,因此运行时配置工具对我来说是最重要的。另外我不认为编译器插件对我来说是一个选项,但是这两个库都可以在没有各自插件的情况下使用,而且冗长度只有很小的增加。我现在正在使用scala-2.9.2。

我也对直接在Scala中进行运行时DI /配置的建议感兴趣,但是将我的整个项目转换为monadic样式也不适合我。

1 个答案:

答案 0 :(得分:18)

通过判断介绍性文档,两个库看起来都非常相似,但它们的实现方式有很大差异。我想警告你,作为其中一个人(scaldi)的作者,我可能无法做出公正的判断,所以你需要用一粒盐来接受我的话。

模块组成和依赖图

它们具有非常相似的DSL,用于绑定,注入以及在托管类的范围内引入Injector / BindingModule的方式(尽管是隐式参数)。

但绑定的容器背后有不同的想法。例如,在Subcut中,可以绑定一个类(是其他类的依赖项)或注入依赖项本身。 但不是两个。如果要在当前绑定的类中注入某些内容,则需要显式提供一些BindingModule作为参数。但是你无法做到这一点,因为你当前的BindingModule(你在哪里定义绑定)正在构建中并且还不存在(当你在其中定义绑定时,你实际上可以使用当前模块它,但是这个模块不知道任何类型的组合,所以我没有找到任何好的方法来实现像这个例子中的跨模块依赖:https://gist.github.com/OlegIlyenko/5623423)你通常不想使用其他模块的具体实例。斯卡尔迪对这个问题的看法非常不同。 Module中定义的每个绑定都是:可以在其他绑定中注入,并且本身可以注入其他依赖项。在定义绑定时,隐式Injector在模块中始终可用。这个隐式注入器不仅代表您当前定义的模块,而且还知道最终的模块组成(如果您决定在某个时刻创建它)。因此,您可以将应用程序分成几个模块,这些模块中的绑定可以相互依赖。

我个人认为,这是两个项目之间最大和最重要的区别。如果您仍然不确定这实际意味着什么,那么我可以建议您尝试两个项目,您会很快注意到Subcut在这方面的限制,以及scaldi解决方案的灵活性。

灵活性

Scaldi是一个非常灵活的库,它允许您自定义它的几乎任何部分。通过使用类型类实现了大部分灵活性。例如Identifier特征。在识别绑定时,Subcut直接使用字符串和类。因此inject方法将String作为参数,而您作为用户无法更改它。另一方面,Scaldi使用Identifier特征而在大多数地方不需要Identifier,但证明CanBeIdentifier类型类存在于您想要用作标识符的特定类型。因此,作为用户,您可以自定义您作为标识符处理的内容以及标识符如何相互关联。绑定的类也是标识符,因此没有特殊情况。

同样的想法用于模块组合,它非常灵活,因为实际组合是使用CanCompose类型类来确保的,您总是从组合中获得最具体的Injector类型(这对于不可变喷射器很重要。所以如果你想用另一个不可变喷射器组成不可变喷射器,你将从它接收ImmutableInjectorAggregation。这同样反映在库的其他部分,如条件和注入器本身(我在下面描述)。

条件绑定

条件绑定被scaldi天真地支持,这是我在其他库中没有看到的东西。因此,您可以声明性地定义绑定是否可用以及何时可用。我觉得它在某些情况下非常有用,例如区分环境(dev / test / prod)。条件绑定使用类型类,因此它们也非常灵活。

动态

从我的观点来看,Scaldi比Subcut更具活力,主要是因为Injector的实现方式。在Subcut中,注入器只是绑定的集合。在scaldi它的界面中有getBinding之类的方法。这意味着它不需要预先知道所有绑定。因此,与Spring或Guice等现有DI框架以及属性文件之类的东西集成非常容易(实际上,Scaldi提供了SystemPropertiesInjector / PropertiesInjector开箱即用的系统属性/属性文件支持,您可以使用你自己的模块。)

不变性

Scaldi在可变模块和不可变模块之间做了很大的区分。可变模块具有更多功能,但也更具动态性和容易出错性。不可变模块更具限制性,但易于推理。而且你通常可以选择。据我所知,Subcut只有一种风格,你可以在可变的上下文中定义你的绑定,但是在你完成它们的定义之后,它是不可变的。

可能存在许多其他较小的差异,但我希望能够突出显示最重要的差异。只是想再次提醒你,我对scaldi只有很好的洞察力,所以我在这里描述的有关Subcut的一些事实和观察结果可能不准确甚至无效。

希望这有帮助。