Scaldi is dependency injection library for Scala. It’s very lightweight (without any dependencies) and provides nice Scala DSL for binding dependencies and injecting them.
If you would Like to get a quick overview of Scaldi, I would recommend you to look at scaldi presentation slides or look at the main page which has some examples and feature highlights. For more hands-on approach, you can check out some example projects which you can play with:
- Scaldi Play 2.4 Example (GitHub, Typesafe activator template)
- Scaldi Play 2.3 Example (GitHub, Blog, Typesafe activator template)
- Scaldi Akka Example (GitHub, Blog, Typesafe activator template)
Activator templates also contain tutorials which show Scaldi basics and also the ways you can integrate in play/akka application.
There are 3 most important traits that you need to know, in order to make dependency injection with Scaldi:
- Injector - it’s a container for the bindings, that you have defined in the module.
- Module - gives you nice syntax to create bindings with
Injectortrait and implicit
Injectorinstance always available when you are defining your bindings
- Injectable - the only responsibility of this trait is to provide you with
injectfunction (so it just provides nice syntax for injecting dependencies). It’s important to understand, that it’s the only purpose of it. So it is completely stateless and knows nothing about actual bindings you have defined in the module. In order to actually find and inject dependencies,
injectfunction always takes an implicit parameter of type
Next sections will describe each of these concepts in more detail.
Injector encapsulates the binding lookup mechanism, by defining following 2 methods:
Out of the box Scaldi comes with several different types of
Injectors. Most of the implementations contain the actual bindings and
provide a DSL to define them (e.g.
Other injectors have a more specific role and serve as a wrapper for other injectors or as an integration point between Scaldi and other libraries.
PlayConfigurationInjector are examples of such
Injector itself is used by the
inject function (which takes an
Injector as an implicit argument) to inject these bindings.
On the other hand injectors also have another property - every injector can be either mutable or immutable. These two types differ in the way lifecycle and injector composition works. Next sections will describe it in more detail.
This section describes the set of standard injectors. There are also other, more specialised, injectors available in other parts of this documentation:
- Play-specific injectors are described in the “Play integration” section
- JSR 330 injectors are described in the “JSR 330 Support” section
Immutable injectors don’t have any lifecycle associated with them. Mutable injectors, on the other hand, have an initialization and shutdown lifecycle phases. Initialization of an injector means that all non-lazy bindings are initialized.
Generally the initialization of
Injector happens automatically as soon as you inject from it for the first time.
But you can also force it by calling
In this example after the
initNonLazy method is called, a new instance of
Server class is created.
After injector is initialized, it is frozen, so
initNonLazy (which is also used internally) is idempotent.
Injector lifecycle also has a shutdown phase during which all binding that defined
destroyWith function would be destroyed.
All built-in mutable injectors are using
ShutdownHookLifecycleManager which means that injector would be destroyed during the JVM
shutdown. But you can also force it by calling the
destroy method is also idempotent. Here is its signature:
As you can see, it also allows you to provide an error handler that would be called if some exception occurs during the
destruction of one of the bindings. The default
IgnoringErrorHandler just prints the stack trace and continues the shutdown procedure.
If error handler returns
true, then an exception will not stop the shutdown procedure, otherwise it
would be stopped.
Module is the most common injector that you can use in most cases. It is mutable injector so it can have a lifecycle and it also provides
nice DSL for the bindings. Here is an example of it’s usage:
DynamicModule is very similar to the Module so it is also a mutable injector which provides the binding DSL. The only
difference is that it allows you bind dependencies in a function and not in the body of the subclass. Here is an example if it’s usage:
ImmutableWrapper is very simple implementation of an injector that just delegates the binding lookup to some other injector that is provided
to it as an argument.
ImmutableWrapper is an
ImmutableInjector. This means that it will guard
delegate from any lifecycle of the parent
composition, if it gets composed with another injector. It also will know nothing about the final composition,
because it is immutable, so it only able to contribute it’s bindings to the composition, but not aware of it at all.
ImmutableWrapper and example of it’s usage can be found in “Implementing Scoped Bindings” section.
Deprecated (since v0.5)
StaticModule is deprecated and will be removed soon. As an alternative you can use
ImmutableWrapper injector to
define an immutability boundary in composition or create your own injector that is marked as
StaticModule is an immutable injector that allows you to define binding as
lazy vals in the body of the subclass:
The resulting bindings have 2 identifiers:
- String identifier which is the name of the class member (e.g.
- Class identifier which is the return type of the
defor the type of
In some cases this can be pretty restrictive, because your bindings can’t have more identifiers or conditions associated with them.
To provide more flexibility Scaldi also allows you to return a
BindingProvider from the member of the class instead of a regular type.
Here is how it looks:
BindingProvider gives you the complete control over the resulting binding.
All property injectors are immutable and allow you to add binding from a property file or
Properties class. Here is a small example showing you how
you can use it:
All properties are available as bindings and each property has only one string identifier and it’s the name of the property. The type of the binding is defined on the inject side. You can inject the following types:
In addition to
PropertiesInjector you can also use
SystemPropertiesInjector which, as you can imagine,
allows you to inject system properties. In fact both these classes extend
RawInjector, which allows you
easily write similar injectors. For example this is the complete implementation of
that provides all properties from play application configuration as a bindings:
Typesafe Config Injector
Typesafe config is natively supported via
It is an immutable injector and allows you to add bindings from a typesafe config. It is very similar to
but it supports many more different property types (generally it supports all property types supported by the typesafe config itself):
Simple Container Injector
SimpleContainerInjector is very simple implementation of injector that allows you to just provide the list of bindings as an argument. It actually takes
Injector => List[BindingWithLifecycle] as an argument, so that you are able to create a list of bindings based on the final
Scaldi also allows you to compose injectors together with
Now when you
inject bindings from the
mainInjector it will lookup bindings from both injectors:
DatabaseModule. The order of the injectors is important. So the binding lookup would
happen from left to right. This means if
DatabaseModule both have a binding with the same identifiers, then one from
ApplicationModule wins and would be injected. You can find more information about binding
overrides in the correspondent section.
There is also another important aspect of the injector composition, namely mutability level. You can compose
mutable and immutable injectors together and the result can be either
which is an injector on itself, so it can be composed further with other injectors. This means that if you are composing
more than 2 injectors together, than they will form a tree, in which internal nodes are the the injector aggregations and
the leafs are the concrete injectors you are composing.
The composition is implemented with the type class
B are the injectors on the left and right side of the composition.
R is the type of the resulting injector, that combines
B in some way. Scaldi defines following rules for the injector composition (which you can customise by providing your own implicit instances of
CanCompose type class):
- immutable injector + immutable injector = immutable injector aggregation
- mutable injector + immutable injector = mutable injector aggregation
- immutable injector + mutable injector = mutable injector aggregation
There is also another special type of the injector which is called
NilInjector. It does not contain any bindings and
is completely ignored during the composition. It can be useful if you want to conditionally compose some injector in one expression:
Mutability in terms of injector composition means two things. First it means, that when aggregation is initialized or destroyed, then it will also recursively initialize or destroy all of it’s mutable children. So in this example:
SomeMutableInjector would be influenced.
SomeImmutableInjector is not touched by the aggregation when
injector.destroy() is called.
Mutability also changes the way binding lookup is done within a module. Every concrete injector like
has an implicit injector instance in scope when you are defining the bindings. That’s because you are able to inject binding within
Module, for example, or you are able to create new instances of classes that take an implicit instance of
Injector as a constructor
argument. But this implicit injector instance is different in mutable and immutable injectors. It would be easier to explain it with a small example:
configModule are mutable injectors, so the implicit injector reference, that they provide within them,
is referencing the final injector composition (
appModule in this case) and not themselves. That’s the reason why you are able
inject [String] ('host) within the
inject [Database] within the
configModule. The reference to the final
composition is propagated during the initialization phase.
Immutable injectors on the other hand do not have any kind of initialisation phase, so the implicit injector, that they provide,
always references themselves. They only can contribute it’s own bindings to the final composition, but they are unable to
consume bindings from it. So if
configModule would have been an immutable injector, then it would fail because of the
Implementing Scoped Bindings
You may be familiar with the concept of scope from other DI libraries out there. The scope of binding defines the context and the lifespan of the binding. So if we are talking about a web application, then you can define bindings in scope of the request or a session, for instance.
Scaldi does not provide any support for the scopes out of the box. More often than not, most useful scopes are tightly coupled with some other library that you are working with in you project, like web framework. So scaldi stays unopinionated in this respect, which allows you to use Scaldi with any library or framework of your choice.
On the other hand, you can easily achieve very similar behaviour just by using abstractions that Scaldi provides out of the box. Here I would like to show you a small example of how you can define a scoped bindings and isolate them from the rest of the bindings by creating some kind of a sandbox for them.
ImmutableWrapper is very simple implementation of an injector that just delegates the binding lookup to some other injector that is provided
to it as an argument. The important thing to notice here is that
ImmutableWrapper is an
ImmutableInjector. This means that it
delegate from any lifecycle of the parent composition, if it gets composed with another injector. It also will know nothing about
the final composition, because it is immutable, so it is only able to contribute it’s bindings to the composition, but not aware of it at all.
Now lets use it:
DbProfileService looks like this:
Even after you destroyed
mainModule still remains intact, even though both of these injectors are mutable,
because we isolated it from the
userScopedModule with the
So as you can see, core Scaldi abstractions are flexible enough to even express concepts that are normally built-in in other libraries.
Injector is pretty straightforward interface to implement (we already saw several examples of it above):
so just by implementing
getBindings methods you can create your own injectors.
You can also reuse some parts of Scaldi implementation. Here is an example of new mutable injector, which can be used
in the injector composition (which on itself means that it would be properly initialized/destroyed and that it also aware of the
final injector composition):
Here is the list of some of the traits that you can mix-in in your own
MutableInjectorUser- contains implicit reference to
injector- the final injector composition which is used by
inject. Injector aggregation will set it during the initialization phase
InjectorWithLifecycle- for the injectors that have lifecycle and can be initialized/destroyed
LifecycleManager- all mutable injectors need to be a
ShutdownHookLifecycleManager- implementation of the
LifecycleManagerthat calls all of it’s destroy callbacks during the JVM shutdown. The implementation is idempotent and thread-safe.
Injectable- provides injection DSL in body of the subclasses (similar to what
Moduleallows you to do, if you extend it)
WordBinder- provides binding DSL in body of the subclasses (similar to what
Moduleallows you to do, if you extend it)
ReflectionBinder- deprecated gathers all
lazy vals in the body of the subclasses and exposes them as a bindings (similar to what
StaticModuleallows you to do, if you extend it)
The list of
Identifiers is used to identify the binding. Unlike many other DI libraries, Scaldi does not hardcode the notion of the
identifier, but rather provides very simple interface and uses it to lookup the bindings:
Out of the box Scaldi comes with following identifiers:
These are the most common one - normally you associate the binding with some type and optionally with the set of string identifiers. In this example:
As you can see,
Symbols are also treated as string identifiers. In this case binding gets these 3 identifiers:
inject will lookup binding with at least following identifiers:
Scaldi also provides a type class in order to treat an existing classes like
Symbol as identifiers:
So if you want some existing class to be treated as an identifier, then you need to provide an implicit instance of
CanBeIdentifier in scope.
Identifier can be marked as required, which would mean, that during injection this identifier must be used in order to get this binding.
By default all built-in identifiers are not required (except
AnnotationIdentifier which described in more detail in “JSR 330 Support” section).
This can be useful if you want to make sure that particular identifier is used regardless of the binding definition order. Binding DSL provides following 2 functions to override default required value of identifier:
required(<identifier>)- makes identifier required
notRequired(<identifier>)- makes identifier not required
Let’s look at simple example that uses non-required identifiers (which is the default for string identifier, as mentioned earlier):
As you see, the
ExperimentalDb will be injected simply because it’s binding defined after
NormalDb and will override it in this particular
We can use
required function in order to make sure, that
ExperimentalDb injected only when client code explicitly asked for it with
Scaldi provides a binding DSL which you can you can use inside of the
Module. Here is an example of how you can create the bindings:
you can start to define binding with either
bind accepts one type parameter, which would be the
TypeTagIdentifier of the binding or in other words it is the type of the bindings.
binding syntax assumes that the type of the binding
is the same to the bound object, so it does not take any type parameters.
You can provide addition identifiers for the binding with
identifiedBy word or
as and if you have more than one additional identifier, then you
After this you can define a condition (only one, but you can combine several conditions with
If you provided several
when conditions, then they would be combined with and.
You can find more information about the conditions in the Conditions section.
The actual value of the binding is bound with the different flavours of
to- defines a lazy binding
toNonLazy- defines a non-lazy binding
toProvider- defines a provider binding
all types of the bindings are described in more detail in the next sections.
You can specify a lifecycle callbacks with
destroyWith words which take a function
T => Unit as an argument, where
T is the type of the binding:
Identifiers, that are used to define a binding, can be marked as
notRequired in order to influence the lookup mechanism
during the injection. More information about this feature can be found in the “Required Identifiers” section.
You can define several bindings for the same set of identifiers. During the binding lookup (when you inject them) the latest
one would be used. You can also un-define the binding by defining the new binding to
None. Here is an example:
In this example when you inject the
server instance will have port 8080 (and only one instance of
HttpServer would be created).
Lazy bindings are defined with the
The instance would be created only once as soon as the binding is injected for the first time. All consequent injects inject the instance that was created first time.
Non-lazy bindings are defined with the
The instance would be created only once, but it would be created as soon as injector (in which it is defined) is initialized. All injects get the same instance of the binding.
Provider bindings are defined with the
A new instance is created each time the binding is injected. This means that each time you inject the binding, you get a new instance.
The lifecycle of the binding consist of the init and destroy phases.
You can define the
T => Unit initialization function with
the same for the function that destroys the object. You can use
The bindings are destroyed together with the
Injector in which they are defined. The initialization depends on
the binding type, but in general it is initialized as soon as new instance of binding is created and before it is injected.
You can also bind things like functions, lists or maps. In other words Scaldi understands generic types and will correctly inject them:
Here is an example how you can inject them:
When you are creating you own
Injectors, you also have opportunity to create your own types of bindings by implementing one of two traits:
Binding- meant to be maintained by immutable injectors
BindingWithLifecycle- meant to be maintained by mutable injectors
Alternatively you can use bindings that come out of the box:
Binding also provides two properties that are very useful when you consume bindings and need to be considered when you are creating a new one:
isEager- tell an injector whether this binding must be initialized during the initialization stage injector itself (an example of such binding is the Non-Lazy Binding)
isCacheable- tells potential users whether this binding is allowed to be cached. Lazy, non-lazy binding can be cached since they are singletons, provider bindings on the other hand can’t be cached. Annotation binding can be both, so it will decide this based on scope. This property is used in Play integration, for example, to decide whether controller instance is allowed to be cached.
Scaldi provides nice DSL for the binding injection. In order to make it available, you need to either import from
or extend it in your class:
Here is an example of how you can inject a binding:
All forms of inject expect an implicit instance of
Injector to be in scope.
If you are injecting in the module definition, then it already provides one for you. If you
are injecting in you own classes, then the best approach would be to provide the implicit injector
instance as a constructor argument, as shown in the example above.
Inject Single Binding
To inject a single binding you need to use
inject method. It takes a type parameter, which is the type of the binding and
would treated as a
TypeTagIdentifier. You can also provide additional binding identifiers using
identified by and separate
you can also skip
identified by part and just write:
Explicit binding type
Please make sure to always provide the type of the binding explicitly (except when you are also providing the default value). Unfortunately compiler can’t correctly infer it in most cases. But don’t worry - the application will not compile if you forgot to specify the type you want to inject.
Inject Provider Function
In addition to
inject, which injects the concrete instance of the binding, you can use
injectProvider which will
inject the function of type
() => T, where
is the type of the binding. It can be useful if the binding itself is defined with
toProvider, so that each time you use it, you will
get the new instance. Other use case would be conditional bindings - if you have defined a binding with the same identifiers but with different
conditions, then this function can return different instances depending on the condition you’ve defined.
Here is an example of how you can use it:
Inject Several Bindings
In some cases you need to inject all bindings that match the identifiers. You can do this by using the
You can also provide additional identifiers as an vararg argument:
If you don’t want to specify the
TypeTagIdentifier, then you can use
injectAll, which just takes the list of identifiers as an argument
and has no type parameters.
You can also specify the default value for the binding. It would be used, if the biding is not found in the
Here is an example of it:
if you already providing some additional identifiers and would like add the default value, then you can use
Use defaults with caution
Even though default values can be useful in some circumstances, I would recommend you to avoid them in most cases. Scaldi provides a lot of tools to help you in this respect. For example you can extract all of your defaults in one/several modules and then compose them with the rest of the application modules. By doing this you will make sure, that defaults are defined only once.
Scaldi supports constructor injection with
injected will create a new instance of the
TokenRepo class and inject all constructor arguments. Here is how the end result will look like:
Multiple Argument Lists
injected also supports multiple argument lists:
This produces following code:
Overriding on Argument Level
Sometimes it’s not enough to just inject based on the type. In this example we have two candidates for
timeout and the last of them would
be injected, which is suboptimal:
injected accept a list of tuples, which allows you to override the injection behaviour for some arguments.
In this case you need to override the injected argument like this:
The argument name can be a
Symbol like shown in example above or a
String. If you made a mistake and injected the wrong type or
misspelled the argument name, then application will not compile (since
injected is a macro and will produce an error at compile time).
injected also respects default arguments in the first argument list. It will use default value if it can’t find the binding to inject.
Here is a small example:
TokenRepo will get a new instance of
Riak for the
db argument anf the
timeout would be
Constructor Injection vs Implicit Injector
Generally you can take two approaches when it comes to the injection of dependencies.
You can define all dependencies of some class as a constructor arguments. In this case you need to provide all of them when you are instantiating the class. Here is how you can do it with Scaldi:
alternatively you can use
injected macro which is described in the previous sections.
Another approach would be to bring the implicit injector instance in scope of class and do injection directly there:
This approach definitely removes some of the boilerplate, but also couples UserService with Scaldi.
I think in most cases it’s the matter of your personal/your teams preference which approach to take. Each of them has a trade-off to make, but in many cases the constructor injection approach is the most clean one, even though it requires a little bit more ceremony, so I recommend you to use it. But every application is different, so you need to decide it for yourself, taking you team and the nature of the project into the consideration.
When you are defining bindings, you can also specify a condition with
This gives you a lot of flexibility in the ways you can define the bindings.
If you have several bindings that have exactly the same condition, then you can group them together in the
when block like this:
This will add the same condition to every binding in the group. If binding itself also defines a condition, then the context condition and the binding’s condition would be combined with and.
Out of the box Scaldi comes with
SysPropCondition which can enable/disable binding based on the system property:
But you can easily convert any predicate in condition like this:
As you already saw, conditions can be composed with
and operators and they also support unary
! for negation.
Here is an example of how
inDevMode is implemented in the play support:
As you can see, you can even use injected dependencies in your condition.
Conditions is a very powerful tool, which can be used in many interesting ways. But please use it with caution, and don’t introduce too many conditions in your application. Also try to keep them intuitive and simple.
Even though Scaldi does not provide explicit testing support or test-kit of any description, the testability was kept in mind from the ground up. If you read this documentation from the beginning, you probably already have an idea how you can test a application that uses Scaldi to do the dependency injection.
The main feature that will help you with testing is the binding overrides. You can can override any binding so that the original binding will never be touched/instantiated and the overriding binding would be used instead.
Biding lookup happens from left to right, so the binding for the
mocksModule would be first looked-up in
db will get an instance of
Riak would not be instantiated at all.
Don't reuse already initialised injectors
As you can see in this example, I used
def to define
mocksModule and I also created a fresh instance of the
AppModule. This is
important, because they both are mutable so they have a lifecycle associated with them. If I will make and
object from the
class), then it will not work correctly if you have more than one test that creates
testModule, because the injector
aggregation will try to initialize it once again when
Database is injected, which is wrong. If you want to reuse an initialised
injector, then you need guard it with an immutable injector as described in the
“Implementing Scoped Bindings” section (but in this case you can’t override the bindings) or you can
simply create a new instance of injector as described in the example above.
Alternatively you can use conditions to define binding that are only active during the tests, but I would discourage you from doing this in most cases - it’s always a good idea to keep your test code separated from the production code.
To add a Scaldi support in the play application you need to include
scaldi-play in the build.sbt:
Dependency injection in Play heavily relies on
ApplicationLoader trait. It’s implementations are responsible to load and initialize
scaldi.play.ScaldiApplicationLoader which you can use to tell Play that you want to use scaldi for
dependency injection in you application. You can do so in
Even though play also has
play.api.inject.Module, just like scaldi, it nothing more than a container for binding definitions, which it collects
from plugins and play core. Play itself will not instantiate or initialize these bindings - it’s task for
ScaldiApplicationLoader got these binding definitions from play, it’s able to construct the
scaldi.Injector from it, which knows how
to initialize and wire all of the bindings from play core, plugins and your application.
In order to provide you application modules to play application, you need to add them to the list of enabled modules in the
ScaldiApplicationLoader understands both scaldi and play-specific modules and able to compose them in one final scaldi injection aggregation.
That is the reason why it able to not only load our scaldi modules, but also play plugins and play core bindings.
Now you can bind controllers as any other class in the Module. For example:
It’s not much different from the way you are using Scaldi outside of the play application. Nice thing about it
is that you no longer need to make
Controller a global singleton
object, but instead it can be a plain
One important thing that you now need to do is to prefix the controller class in the conf/routes file with
There is an example of how you can define a route for the
By doing this, you are telling Play to use Scaldi to resolve the controller instance instead of trying to use it’s own internal mechanisms for it.
Please note, that if you are using
InjectedRoutesGenerator, then you don’t need to prefix your controllers with
@ in the conf/routes file:
Note for plugin developers
Since plugins in Play are normal modules, it’s tempting to define them as scaldi modules. I would encourage you to avoid using scaldi-specific
modules in plugin itself. Ideally you need to provide
play.api.inject.Module for your plugin and use JSR 330 annotations, so that users
of your plugin have choice of DI library in their own applications.
Play Application Lifecycle
ScaldiSupport is now deprecated and you generally should avoid usage of
GlobalSettings, you need to use scaldi’s own lifecycle as a lifecycle
of your application. So your application starts then
Injector is initialized.
If you need to eagerly initialize some bindings, then you can use non-lazy bindings:
If some additional code need to be executed when binding is initialized or destroyed, then I would recommend you to look at “Binding Lifecycle” section:
Play itself provides a binding for
ApplicationLifecycle class which you can inject use to add additional stop logic:
Within a Play application you can add
scaldi.play.ControllerInjector which will create controller bindings on the fly, which means that you don’t need to
create then explicitly by yourself:
Controller class should meet following requirements to be available for the
- It should extend
- It should have constructor that takes and implicit
Injectoras an argument
Play support also makes following bindings automatically available for you to inject (as well as any other play-specific bindings, like
Application- the Play
Applicationin which injector lives
Mode- the mode of the Play
Configurationof the Play
Following conditions are available for you to use in the binding definition:
They all use Play
Applications mode. Here is an example of how you can use them:
Injecting Play Configuration
scaldi-play provides integration with Play configuration (
conf/application.conf) out of the box.
So you can, for example, define
greeting.official property there:
and then just inject it anywhere in your application
You can also inject other primitive types like
Boolean and not only
String (similar to
If you would like to use
configuration instance directly, then you need inject it like this:
scaldi-play caches all controllers to ensure the fast controller retrieval times. It also considers
property bindings, so it will not cache controllers that are bound with
If you wish to disable caching, then you can do so with
scaldi.controller.cache property in
Testing of Play Application
Testing support comes in form of
scaldi.play.ScaldiBuilder classes and conceptually very similar to testing support
described in the official documentation:
ScaldiApplicationBuilder constructor has a lot of different arguments (with reasonable defaults) to customize different parts of your application.
For example you can provide additional application modules, change configuration or even influence how configuration or modules are loaded.
Instead of using
build() method, which return you a Play
Application, you can also use
buildInj() which will return
This can be useful, if you would like to inject some bindings:
Companion object of
ScaldiApplicationBuilder also has two helper methods:
They allow you to run test in the context of running application/injector:
Both of these allow you to provide bunch of arguments to customize a fake application, just like
Here is an example of different ways to provide additional configuration:
As you can see,
ScaldiApplicationBuilder also has builder methods for different aspects of application.
If you wish, you can also override the configuration loading function:
In order to provide application modules,
ScaldiApplicationBuilder provides a constructor argument
modules which would prepend provided modules to the
final module composition. You can also use
appendModule(...) for this. Prepended modules will have the highest priority
during the binding lookup - it is very useful for test bindings since they will override bindings from other modules. Appended modules would
be added to the end of a module composition. Please see “Injector Composition” section for more details. Here is an example:
Sometimes you want to have complete control over the module composition. This means, that you would like to create composition
from scratch and disable default module loading mechanism. You can do it with the help of
As you can see in this example, you also need to compose
BuiltinModule of play and possibly plugin modules (like cache plugin in this case)
in order to construct complete application.
loadModules = (_, _) => Seq.empty in this case completely disables default module loading mechanism.
In some case you need to define some fake routes in the tests, it’s something you was able to do with the
FakeApplication(withRoutes = ...) before.
FakeRouterModule for this purpose - it’s just a
scaldi.Injector, so you can add it to the module list of your test application.
Here is an example of it’s usage:
Play 2.3.x Support
Play 2.3.x is still actively supported. In order to use scaldi in Play 2.3.x project, you need to use different dependency:
Older play versions had very limited support for dependency injection, so main integration point was
You need to mix-in
ScaldiSupport trait in the
Global object to be able to provide your applications’s modules:
As you can see, you also need to implement
applicationModule method. By doing this you tell play which Injector should be used
to lookup the controller instances. This is also a good place to compose the main injector for your Play application.
To add a Scaldi support in the akka application you need to include
scaldi-akka in the build.sbt:
The only new thing that
scaldi-akka adds is
AkkaInjectable, which provides 2 additional inject methods:
injectActorRef- creates a new actor with the help of
ActorReffactory which should be implicitly available in the scope.
Actor, so that you can create new
Actors yourself with the help of the
ActorRef factory can be one of two things:
ActorContext- it always implicitly available within an
Actorand can be used to create a new actors in the context of current actor
Here is a small example of how you can use
AkkaInjectable to inject (which actually means create in the case of actors) another actor:
Or alternatively, if you want to create an actor somewhere else (not inside of an actor), you need to bring an implicit
ActorSystem in the scope:
We have created some actors that are able to use
inject. The only thing that remains now is to create a module that binds them together
with other dependencies and the
I would like to point out how
Actor are bound. It is important, that you bind them with
It will make sure that Scaldi always creates new instances of the
Actor classes when you inject them
injectActorProps. These two methods actually use Akka mechanisms to configure an actor
instance under-the-hood, but the actor instance creation itself is always delegated to Scaldi.
During this process, Akka requires a delegate to always create new instances of an actor, so by binding
toProvider you are fulfilling the protocol, that Akka implies.
In some cases you may want to create a singleton actors - they will be created and bound once and then injected in other actors that want to work with them.
Generally I would recommend to create actors within another actors and then send references around to propagate them to all places that want to use this actor ref, because in most cases you also need to take care of proper actor supervision hierarchy.
But If you have some singleton actors that are sitting under the system guardian’s supervision then what you can do is to create another binding that will create an actor ref for the singleton actor:
then you can just
inject it in other actors as normal:
You can improve it a little bit by creating a custom
Identifier for it instead of using a symbol or string.
JSR 330 Support
Intended for integration
JSR 330 support can be very helpful for integration with other libraries and frameworks. It also useful during the migration as you move your existing codebase to scaldi, assuming that you used another JSR 330 compatible DI library (like Google Guice). If you are starting from scratch or don’t need this kind integration, then I would recommend to avoid JSR 330 annotations and use normal Binding DSL.
Scaldi implements JSR 330 (Dependency Injection for Java) spec. This allows you to bind JSR 330 annotated classes and inject scaldi bindings from them. From the optional part of JSR 330 spec, only private member injection is supported (which means that static injection is not supported).
To add JSR 330 support, you need to add one extra library dependency in your project:
In order to bind JSR 330 annotated class you can use
annotated syntax when you are defining a binding (all JSR 330 support resides in the
This will define a new
AnnotationBinding which itself is a
V8Engine has a
javax.inject.Singleton scope annotation,
then the binding would behave like a scaldi’s
LazyBinding otherwise it will behave like
The only supported JSR 330 scope is a
javax.inject.Singleton scope. Custom scope annotations are not supported and will result in
JSR 330 support also provides
OnDemandAnnotationInjector which defines JSR 330 compliant bindings on-the-fly (when they are injected).
Scaldi also supports
javax.inject.Named as well as any other custom
is treated as normal
StringIdentifier. Any other custom qualifier would become an
AnnotationIdentifier. In order to define a
AnnotationIdentifier you can use a
qualifier function available in
In some cases you need to bind and instance of
Annotation instead of just type. This can come in handy when your
Qualifier annotations have fields.
annotation function allows you to do it like this:
In this example result
SomeQualifierImpl.of() must return an instance of a class that implements some annotation interface.
Of course you can also use the same syntax when you are injecting them:
AnnotationIdentifier is a required by default, which means that you must use it when you are injecting the binding
(see “Required Identifiers” section fro more details). If you want to make a standard identifier required (like
you need to use
required function with this identifier: