Akka.NET and Unity IoC

Even though Akka.NET supposedly supports dependency injection through its DI libraries (e.g. Akka.DI.Unity), it’s not very good. In the documentation you’ll see examples like:

Context.DI().Props<MyActor>()

That Props call doesn’t take any arguments so there’s no way to actually inject parameters into the call. Let’s say we have this actor:

public class MyActor : ReceiveActor {
  public MyActor( string a, IFoo b, IBar c ) {
    // ...
  }
}

Further say we want to specify a but let Unity resolve IFoo and IBar from configuration. If we were just creating the object normally we would write:

var myActor = UnityContainer.Resolve<MyActor>( 
  new ParameterOverride( "a", "ABC" ) 
  );

But that’s not how we create actors. We create actors using ActorOf and specify Props. We do this so that Akka.Net can recreate the actors if they fail.

If we were to create the actor normally without dependency injection we would write something like:

var myActorRef = actorRefFactory.ActorOf( 
  Props.Create( () => new MyActor( "ABC", ??, ?? ) 
  );

If we do that, we aren’t getting our interfaces from Unity.

So let’s try dependency injection. If we were to use Akka.DI.Unity we would have:

var myActorRef = actorRefFactory.ActorOf(
  Context.DI.Props<MyActor>() 
  );

But then there’s no way to specify our parameter.
We’re stuck. We can specify all parameters or none but can’t specify some and let unity take care of the others like we usually want.

Here’s a way you can do it that doesn’t involve the Akka.DI libraries:

IIndirectActorProducer

It turns out that Props is not the only way to create an actor. If you dive into the source code, you can see that there’s a IIndirectActorProducer class that will create an actor without Props by implementing a Produce method.
Here’s an implementation that takes a IUnityContainer and the ResolverOverrides in its constructor and uses them to create the actor when called:

    /// <summary>
    /// A <see cref="IIndirectActorProducer" /> that uses a <see cref="IUnityContainer" /> to resolve instances.
    /// </summary>
    /// <remarks>
    /// This is only used directly by the <see cref="UnityActorRefFactory"/>
    /// </remarks>
    /// <typeparam name="TActor"></typeparam>
    internal sealed class UnityActorProducer<TActor> : IIndirectActorProducer where TActor : ActorBase {

        /// <summary>
        /// The resolver overrides.
        /// </summary>
        private readonly ResolverOverride[] _resolverOverrides;
        /// <summary>
        /// The unity container.
        /// </summary>
        private readonly IUnityContainer _unityContainer;

        /// <summary>
        /// The constructor.
        /// </summary>
        /// <param name="unityContainer">The unity container.</param>
        /// <param name="resolverOverrides">The resolver overrides.</param>
        public UnityActorProducer( IUnityContainer unityContainer, params ResolverOverride[] resolverOverrides ) {
            this._unityContainer = unityContainer.CreateChildContainer();
            this._resolverOverrides = resolverOverrides;
        }

        /// <summary>
        /// See <see cref="IIndirectActorProducer.ActorType"/>
        /// </summary>
        public Type ActorType => typeof( TActor );

        /// <summary>
        /// See <see cref="IIndirectActorProducer.Produce" />
        /// </summary>
        /// <returns></returns>
        public ActorBase Produce() {
            // Create the actor using our overrides
            return this._unityContainer.Resolve<TActor>( this._resolverOverrides );
        }

        /// <summary>
        /// SEe <see cref="IIndirectActorProducer.Release" />
        /// </summary>
        /// <param name="actor"></param>
        public void Release( ActorBase actor ) {
            // Do nothing
        }

    }

We can create Props using the producer like this:

        /// <summary>
        /// Creates <see cref="Akka.Actor.Props" /> using the <see cref="IUnityContainer" /> and any <see cref="ResolverOverride" />s provided.
        /// </summary>
        /// <typeparam name="TActor"></typeparam>
        /// <param name="unityContainer"></param>
        /// <param name="resolverOverrides"></param>
        /// <returns></returns>
        public Props Props<TActor>( IUnityContainer unityContainer, params ResolverOverride[] resolverOverrides ) where TActor : ActorBase {
            // Use a UnityActorProducer to create the object using the container and resolver overrides.
            return Akka.Actor.Props.CreateBy<UnityActorProducer<TActor>>( 
                unityContainer, 
                resolverOverrides 
                );
        }

So creating our actor would look like this:

var myActorRef = Context.ActorOf(
  Props<MyActor>( 
    unityContainer, 
    new ParameterOverride( "a", "ABC" ) 
  )
  );

It uses our resolver overrides for the first parameter and the unity configuration for our additional parameters, just as we want.

Akka.NET, Prism, Unity, and WPF

Since I’ve been reading up on Reactive Extensions, I listened with interest to the recent .NET Rocks! podcast on the subject. During the conversation, Akka.NET was mentioned.

Akka.NET is another reactive technology. It’s an implementation of the Actor model. Basically, you break down an application’s functionality into small computational units called Actors which have limited state and communicate via message passing. There are parallels in Rx’s concept of observables and observers. Akka.NET also provides the kind of supervision hierarchy that you find in erlang, which is that an actor has child actors and when those child actors fail, the parent can resume or restart the failed children. This makes the application ‘self healing’.

I watched two Pluralsight course on Akka.NET by Jason Roberts, Building Concurrent Applications with the Actor Model in Akka.NET and Building Reactive Concurrent WPF Applications with Akka.NET (subscriptions required for both links). The former gives an overview of Akka.NET and the latter applies it to an MVVM WPF application.

In the demo MVVM application, the author uses Akka.NET with Ninject dependency injection and the MVVM Light toolkit. Personally, I prefer Unity and Prism, so as an exercise for myself I created the demo using those two languages. The result is on GitHub at https://github.com/mkb137/AkkaPrismUnityDemo.

The project consists of
* Akka.DI.Unity – A copy of Akka.NET’s Akka.DI.Unity upgraded from Unity 3.5 to Unity 4.0. No code changes were required otherwise.
* AkkaPrismUnityDemo – The Prism shell project
* AkkaPrismUnityDemo.Infrastructure – The common infrastructure project (which in this simple demo only contains the region names)
* AkkaPrismUnityDemo.Modules.Stocks – The main module containing the demo code.

A screenshot of the result is shown at the top of this post. In it, the view model creates actors which then have knowledge of the view model that created them and will call methods on the view model when messages are received and processed.

Here a view model creates an actor and passes it a reference to itself:

this.StockToggleButtonActorRef = 
    this.UnityContainer.Resolve<ActorSystem>()
    .ActorOf( 
        Props.Create( () => new StockToggleButtonActor( 
            this.StocksCoordinatorActorRef, 
            this, 
            this.StockSymbol
        ) 
    ) 
);

Here the actor makes a callback to the view model:

this.Receive<ToggleStockMessage>( message => {
    this._stocksCoordinatorActorRef.Tell( new WatchStockMessage( this._stockSymbol ) );
    this._viewModel.UpdateButtonTextToOn();
    this.Become( this.ToggledOn );
} );

Like Rx and its Observables/Observers, messages are handled on the thread pool so actors will make full use of the processors available on the machine with no extra effort from the developer.

It’s an interesting technology. Compared to Rx, Akka is missing some of Rx’s advanced publish/subscribe methods like the ability to buffer or throttle messages. It does have a Sample equivalent via the scheduler’s ScheduleTellRepeatedly method. On the plus side, it provides the supervision hierarchy and provides a more natural message pipeline. With Rx it seems like having an object that is both observer and observable (i.e. is part of a pipeline), while supported, is somehow discouraged.