Comparing Subcut and Scaldi

2.1k views Asked by At

I am looking at SubCut and Scaldi to use in my projects. The examples provided in their respective Getting Started documents seem very similar. Neither project seems to provide documentation beyond Getting Started and scala docs.

Could somebody summarize the practical differences between these frameworks primarily in terms of features and maturity/stability. I am looking into these packages because I need to be able to create and compose configuration dynamically at runtime. Runtime configuration is the main reason I am looking at these libraries instead of using implicits and/or the layer cake pattern to do DI/configuration, so run time configuration facilities are the most important to me. Also I do not think compiler plugins are an option for me, but both of these libraries can be used without their respective plugins with only a small increase in verbosity. I am on scala-2.9.2 for the moment.

I am also interested in suggestions for doing runtime DI/configuration directly in Scala, but converting my whole project to monadic style is also not an option for me.

1

There are 1 answers

6
tenshi On BEST ANSWER

Both libraries may look pretty similar by judging introductory documentation, but they have big differences in the way how they are implemented. I would like to warn you, that as an author of one of them (scaldi), I probably unable to make a fair judgment, so you need to take my words with a grain of salt.

Module composition and dependency graph

They have very similar DSL for binding, injection and the way you bring Injector/BindingModule in scope of the managed class (though implicit parameter).

But containers of the bindings have different ideas behind them. For example in Subcut a class can be either bound (be a dependency for other classes) or inject dependencies itself. But not both. If you want to inject something in class that you are currently binding, then you need explicitly provide some BindingModule as an argument. But you can't make it generically because your current BindingModule (where you are defining binding) is under construction and does not exist yet (You can actually use current module when you are defining bindings within it, but this module is not aware of any kind of composition, so I have not found any good way to implement cross-module dependencies like in this example: https://gist.github.com/OlegIlyenko/5623423) and you normally don't want to use concrete instances of other modules. Scaldi take on this problem is very different. Each binding that is defined in the Module is both: can be injected in other bindings and itself can inject other dependencies. And implicit Injector is always available within a module when you are defining your bindings. This implicit injector represent not only module you are currently defining, but it also aware of the final module composition (if you will decide to create it at some point). So you can separate your application in several modules, and bindings within these modules can have dependencies between each other.

I personally think, that it's the biggest and most important difference between two projects. If you still not sure what this practically means, then I can recommend you to try both projects out and you will quickly notice how restrictive Subcut is in this respect, and how flexible scaldi's solution is.

Flexibility

Scaldi is very flexible library, that allows you to customize almost any part of it. Most of this flexibility achieved though usage of type classes. For example Identifier trait. Subcut works directly with strings and classes when it comes to identifies for the bindings. So inject method takes String as argument and you, as user, can't change it. Scaldi from the other hand uses Identifier trait instead and in most places requires not Identifier, but evidence that CanBeIdentifier type class exist for some particular type you want to use as identifier. So you, as user, can customize what you treat as identifier and how identifiers relate to each other. The class of the binding is also identifier so there is no special cases.

The same idea is used for module composition which is very flexible because actual composition is made with CanCompose type class which makes sure, that you always receive the most concrete Injector type out of the composition (this is important in case of immutable injectors. So if you want to compose immutable injector with another immutable injector you will receive ImmutableInjectorAggregation from it). The same is reflected in other parts of the library like conditions and injector itself (I described it below).

Conditional bindings

Conditional bindings are naively supported by scaldi and it something that I have not seen in other libraries. So you can declaratively define whether your binding is available or not, and when. I find it very useful in some situations like distinguishing between environments (dev/test/prod). Conditional bindings use type-classes, so they are very flexible as well.

Dynamic

From my point of view, Scaldi is more dynamic than Subcut mostly because of the way Injector is implemented. In Subcut injector is just a collection of bindings. In scaldi it's interface that has method like getBinding. This means that it don't need to know all bindings upfront. So integration with existing DI frameworks like Spring or Guice and things like properties files is very easy (actually Scaldi provides system properties/properties file support out of the box with SystemPropertiesInjector/PropertiesInjector, which you can compose with your own modules).

Immutability

Scaldi makes big distinction between mutable and immutable modules. Mutable modules have more features but also more dynamic and error-prone. Immutable modules are more restrictive but make it easy to reason about. And you generally have a choice. As far as I know, Subcut has only one flavor where you can define your bindings within mutable context, but after you've finished defining them, it's immutable.

There are probably many other smaller differences, but I hope I was able to highlight most important ones. Just want to remind you again, that I only have good insight on scaldi, so some facts and observations about Subcut, that I have described here, may be inaccurate or even invalid.

Hope this helps.