19

我正在寻找在我的项目中使用的SubCutScaldi。他们各自的入门文档中提供的示例看起来非常相似。除了Getting Started和 scala 文档之外,这两个项目似乎都没有提供文档。

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

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

4

1 回答 1

18

从介绍性文档来看,这两个库可能看起来非常相似,但它们在实现方式上存在很大差异。我想警告您,作为其中之一(scaldi)的作者,我可能无法做出公正的判断,因此您需要对我的话持保留态度。

模块组成和依赖图

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

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

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

灵活性

Scaldi 是一个非常灵活的库,它允许您自定义它的几乎任何部分。大多数这种灵活性是通过使用类型类来实现的。比如Identifier特质。当涉及到绑定的标识时,Subcut 直接与字符串和类一起工作。所以inject方法String作为参数,你作为用户不能改变它。另一方面,Scaldi 使用Identifiertrait 代替,并且在大多数地方不需要Identifier,但有证据表明CanBeIdentifier您想要用作标识符的某些特定类型存在类型类。因此,作为用户,您可以自定义您视为标识符的内容以及标识符之间的关系。绑定的类也是标识符,所以没有特殊情况。

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

条件绑定

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

动态的

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

不变性

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

可能还有许多其他较小的差异,但我希望我能够突出最重要的差异。再次提醒大家,我只对 scaldi 有很好的了解,所以我在这里描述的关于 Subcut 的一些事实和观察可能不准确甚至无效。

希望这可以帮助。

于 2013-05-20T23:53:30.050 回答