Just as a quick follow-up to my previous post, I thought I’d note that the official Akka blog has published a post regarding Akka and dependency injection (kind of weirdly expressed as a mini white paper, as though the internet at large had issued an RFP for an actor-based concurrency system with dependency injection).
While, as I mentioned before, I should emphasize that I’m by no means an expert in Akka or actor best practices, I’m not convinced that this document addresses my particular concerns with the intersection of Akka and dependency injection. I’m still thinking about a larger post breaking down the approaches to this topic that I’ve seen online, but this one sort of falls into the “mock stuff outside of Akka” camp.
The document has two main points: firstly, if you have an existing dependency-injected service, you can pass along a factory which knows where to find it to the Props
constructor of an actor, and there’s a way to attach a DI application context to an ActorSystem
to support this, in what seems like a pretty convenient way. Secondly, if you need to expose an interface from actors to an existing system based on a DI framework, you can include an ActorSystem singleton in your DI object graph, and then expose a sort of regular-object facade over it which finds specific actors and returns either ActorRefs
or futures resulting from sending ask messages to them.
That’s all well and good, but it seems more like a way to integrate between Akka and an existing synchronous DI-based system than anything that makes dependency injection useful or usable inside a purely Akka-based system. (In particular, the document’s unfortunate final section seems to be aimed squarely at recalcitrant middle managers who need to be convinced that a move to Akka will not result in a whole bunch of now-legacy code needing to be tossed out.) While I’m not incredibly interested in this topic myself, I thought Akka already had a talking point for this integration problem in the form of “typed actors“.
The bit that I still haven’t seen addressed is that if Akka likes actors to explicitly manage the lifecycles of other actors they supervise, there doesn’t seem to be any room for the inversion of control that is the hallmark of dependency injection frameworks in the first place. To put it in more concrete terms, if I’m running a partial integration test of my simple notification service and I want it to have a real database actor and mock REST web service actors, how can I tell the actor that supervises all the HTTP worker actors to create mock actors instead of live ones?
I have a half-formed idea of how this could work that involves having a sort of service locator / factory actor which is responsible for actor instantiation, but the idea in my head doesn’t particularly jibe with Akka’s supervision hierarchy, which as far as I can tell is coupled very tightly to actor instantiation.