Typesafe Activator

Scaldi Akka Example

Scaldi Akka Example

scaldi
Source
June 22, 2014
scaldi akka scala dependency-injection basics

Scaldi is lightweight Scala dependency injection library. In this project you will find an example of Akka application that uses Scaldi for dependency injection.

How to get "Scaldi Akka Example" on your computer

There are several ways to get this template.

Option 1: Choose scaldi-akka-example in the Typesafe Activator UI.

Already have Typesafe Activator (get it here)? Launch the UI then search for scaldi-akka-example in the list of templates.

Option 2: Download the scaldi-akka-example project as a zip archive

If you haven't installed Activator, you can get the code by downloading the template bundle for scaldi-akka-example.

  1. Download the Template Bundle for "Scaldi Akka Example"
  2. Extract the downloaded zip file to your system
  3. The bundle includes a small bootstrap script that can start Activator. To start Typesafe Activator's UI:

    In your File Explorer, navigate into the directory that the template was extracted to, right-click on the file named "activator.bat", then select "Open", and if prompted with a warning, click to continue:

    Or from a command line:

     C:\Users\typesafe\scaldi-akka-example> activator ui 
    This will start Typesafe Activator and open this template in your browser.

Option 3: Create a scaldi-akka-example project from the command line

If you have Typesafe Activator, use its command line mode to create a new project from this template. Type activator new PROJECTNAME scaldi-akka-example on the command line.

Option 4: View the template source

The creator of this template maintains it at https://github.com/scaldi/scaldi-akka-example#master.

Option 5: Preview the tutorial below

We've included the text of this template's tutorial below, but it may work better if you view it inside Activator on your computer. Activator tutorials are often designed to be interactive.

Preview the tutorial

An example of Akka application that uses Scaldi for dependency injection

Akka integration has not much to add to the core library in order to smoothly integration with it. In order to use it you need to add scaldi-akka to the SBT build, so let's do this first:

libraryDependencies ++= Seq(
    "org.scaldi" %% "scaldi-akka" % "0.3.1"
)

Now you should be ready to go. 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 ActorRef factory which should be implicitly available in the scope.
  • injectActorProps - injects Props for the Actor, so that you can create new Actors yourself with the help of the ActorRef factory.

If you still wondering what Injectable actually is, I can recommend you to read one of my previous posts. It explains the basic concepts of the library and shows an example application that uses Scaldi for the dependency injection.

I mentioned ActorRef factory above. It can be one of two things:

  • ActorContext - it always implicitly available within an Actor and can be used to create a new actors in the context of current actor
  • ActorSystem

Here is a small example of how you can use AkkaInjectable to inject (which actually means create in case of actors) another actor:

class Receptionist (implicit inj: Injector) extends Actor with AkkaInjectable {
    val userService = inject [UserService]

    val orderProcessorProps = injectActorProps [OrderProcessor]
    val priceCalculator = injectActorRef [PriceCalculator]

    def receive = {
        case PlaceOrder(userName, itemId, netAmount) =>
            val processor = context.actorOf(orderProcessorProps)
            // ...
    }
}

Or alternatively, if you want to create an actor somewhere else (not inside an actor), you need to provide an implicit ActorSystem in the scope:

import scaldi.akka.AkkaInjectable._

implicit val appModule: Injector = // ...

implicit val system = inject [ActorSystem]

val receptionist = injectActorRef [Receptionist]

So far so good. 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 ActorSysyem itself:

class OrderModule extends Module { bind [UserService] to new SimpleUserService

bind [ActorSystem] to ActorSystem("ScaldiExample") destroyWith (_.shutdown())

binding toProvider new Receptionist binding toProvider new OrderProcessor binding toProvider new PriceCalculator }

As you can see, now you also can define how binding can be destroyed with the destroyWith function. It is part of the binding lifecycle feature that was introduced in Scaldi version 0.3.

At this point I would like to point out how Actor are bound. It is important, that you bind then with toProvider function. It will make sure, that Scaldi always creates new instances of the Actor classes when you injecting them with injectActorRef or 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 the delegate to always create new instances of an actor, so by binding Actors with toProvider you are fulfilling the protocol, that Akka implies.

comments powered by Disqus