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.
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(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 theBindingModule
as an argument. But you can't make it generically because your currentBindingModule
(where you are defining binding) is under construction and does not exist yetModule
is both: can be injected in other bindings and itself can inject other dependencies. And implicitInjector
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. Soinject
method takesString
as argument and you, as user, can't change it. Scaldi from the other hand usesIdentifier
trait instead and in most places requires notIdentifier
, but evidence thatCanBeIdentifier
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 concreteInjector
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 receiveImmutableInjectorAggregation
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 withSystemPropertiesInjector
/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.