Scaldi: Dependency injection library in scala


Scaldi is the lightweight dependency injection library written in scala and it provides scala DSL for binding dependencies and injecting them.

Its depends on three concepts.

Injector – container for bindings.

Module –  where we define bindings and it extends Injector.

Injectable – trait which provide DSL for injection.

In this blog we will see how can we use it with Akka.

1. First add scaldi library dependency in your project build.sbt


"org.scaldi" %% "scaldi-akka" % "0.4"

2. Suppose we have an actor as below which does sum of two integer and send result back to its sender.


class SumActor extends Actor {
def receive = {
case Sum(a, b) =>
sender ! SumCalculated(a + b)
}
}

Below are the messages used for communication between actors.


case class Sum(a: Int, b: Int)
case class SumCalculated(sum: Int)

3. Create an actor who delegate the job to this SumActor and uses scaldi library api to inject props of SumActor.


import akka.actor.Actor
import scaldi.Injector
import akka.actor.ActorRef
import akka.actor.PoisonPill

class SumCalculater(implicit inj: Injector) extends Actor with
AkkaInjectable {

val sumActorProps = injectActorProps[SumActor]

def receive = work

val work: Receive = {

case sum: Sum =>
val sumActor = context.actorOf(sumActorProps)
sumActor ! sum
context become doSumAndSendResult(sum, sender)

def doSumAndSendResult(sum: Sum, reportTo: ActorRef): Receive = {
case SumCalculated(sum) =>
println("calculated sum.....")
reportTo ! sum
}
}
}

4- Now we will create a simple application using scaldi as below.

AkkaInjectable trait  provide various methods for dependency injection.

injectActorRef – creates a new actor using actorRef factory.

injectActorProps – inject props for the actor.


import scaldi.Module
import akka.actor.ActorSystem
import akka.actor.Inbox
import scala.concurrent.duration._

object SumApplication extends App with AkkaInjectable {

implicit val applicationModule = new SumModule :: new AkkaModule
implicit val system = inject[ActorSystem]
val sumCalculater = injectActorRef[SumCalculater]
val inbox = Inbox.create(system)

inbox send (sumCalculater, Sum(3, 4))
val sum = inbox.receive(5 seconds)
println(sum)
}

class SumModule extends Module {
binding toProvider new SumCalculater
binding toProvider new SumActor
}

class AkkaModule extends Module {
bind[ActorSystem] to ActorSystem("SumActorSystem") destroyWith (_.shutdown())
}

In class SumModule we provide binding for all actors which we want to inject as dependency in  application. In class AkkaModule we provide binding for ActorSystem.

We can combine these two module using  :: operator.

Related code can be found in github repo.  Learn more about scaldi.

About Piyush Mishra

Software Consutant
This entry was posted in Scala. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s