I want to use Guice Dependency Injection with Akka Actors.

Akka documentation, here, suggests to use IndirectActorProducer for dependency injection. But it is not explained, or I don't understand, the reason.

In my opinion it should be used to avoid passing not serializable components/services inside Props. But other examples that I have found (here or here) pass the whole Injector class that I'm quite sure it is not serializable.

So my questions are:

  1. How and why IndirectActorProducer should be used?
  2. Props must be serializable? It is fine to pass Guice Injector as a Props parameters?

I known that there are similar questions, but in my opinion there isn't a clear answer yet:

1 Answers

Mateusz Kubuszok On

It might not be the answer you are looking for so keep the question open in case someone else provide more Guice-bases answer.

Basically the reason we use DI frameworks/libraries is because of overhead of passing arguments manually and maybe also interface-implementation decoupling (though the later can be simply solved by passing down functions in constructors and using them to create the implementation, so it is not that much of an argument).

In Scala, at least in codebases that goes away from Java for simpler projects people just pass down things as arguments:

class MyActor(name: String, surname: String) extends Actor { ... }

def createActor(name: String, surname: String) =
   system.actorOf(Props(MyActor.class, name, surname))

People, who don't like to do things manually, have some other options, but most of them are based on compile time reflection like e.g. Macwire which uses types to inject things:

// tags used to distinguish things - something like named instance in Guice
// but on types instead of strings
sealed trait Name
sealed trait Name
class MyActor(name: String @@ Name,
              surname: String @@ Surname) extends Actor { ... }

def createActor(name: String @@ Name, surname: String @@ Surname) =
   // wire is a macro that puts arguments into constructor by looking at
   // variables in the current scope and their types

Since here linking errors appear at compile time and not during runtime, a lot of people consider this easier to maintain than solutions proposed by Java ecosystem.

And because this macro just unrolls to plain old argument passing code as long as your arguments are serializable you have no issues like unserializable Injector.