Akka.NET #7: Creating and accessing Actor System with Dependency Injection Container

By | October 1, 2017

A while ago I wrote about creating Actor System and top-level actors. Sadly it was stored in a static field. And keyword static is … let’s say it’s not one of my favourites. Today I’ll show you how I’m doing the exact same thing but in Dependency Injection container.

One of my favourite IoC containers is Ninject and I’m using it almost everywhere. In my pet-project, I’m using it with Nancy FX, but every code sample is also usable with ASP.NET MVC.

First of all, configuration and creation of Actor System should be moved out of any static helper class we’ve had before.

It’s rather simple class. Since we’re going full abstraction let’s extract System property to an interface. It’s possible to skip this part, but if you’re going to inject this container anywhere, you really should have an interface for that.

My ActorSystemContainer have only one top-level actor and I’m not planning to include more of them anytime soon, so I’m creating it in the constructor. If you have more of them, you should probably think about something better than that.

Now our class is almost ready. All we’ll need is some kind of interface that will allow us to expose our IActorRef of our actors and inject them in this interface. In my case, it’s really simple because I have only one top-level actor but in a lot of cases, you’ll have more of them. And all of them are exposed as IActorRef with no generic parameter or any other way to identify referenced actor type at all. So there is no way to inject IActorRef somewhere, send a message to it and trust our IoC will give us a reference to an actor of a type we’re going to need. So let’s create yet another interface to solve this little problem.

A generic parameter, in this case, is just a marker with constraint to ensure that it will always be of a type that is also an actor. Why we’re doing that? It’s quite simple. In C# we can implement interfaces explicitly and by doing that we’re allowed to declare methods and properties with exactly the same signature (return type, parameters and name). How it’ll look inside of our container?

So now every one of our IActorRef to an actor created inside of a container is paired with an explicitly implemented getter. We can have as many of them as we want and they all will differ only by generic parameter.

How will we inject our IActorRef and send a message to it now? As soon as we’ll bind it in our IoC(we’ll get there soon!) we should be able to do something like that.

As you can see it really is pretty simple and as long as you know the type of actor you want to send a message to, everything will go great. And to be honest I think you should always know about the destination of your message (unless you’re using publisher/subscriber pattern).

And how to create and configure Actor System in our Dependency Injection container? In Ninject and any other DI I’ve worked with there is always a possibility to bind something in the scope of a singleton. Which means a lifetime of instances of class bounded this way is the same as kernel or container itself. In Ninject we should call InSingletonScope() method during binding.

And just a few lines below we need to bind each of our top-level actors references like that.

Not that I’m using ToMethod() method here. I’m doing that because if I’ll just bind an interface to type Ninject would create a new instance of ActorSystemContainer each time we would inject IKnowActor anywhere. Doing things this way ensures that every time we’ll get a single instance from our IoC.

As you can see it really isn’t hard. I’m using this for some time now and it gets the job done. If you using any other way of doing things like that or have any ideas how to do this – please share your thoughts in comments.