I am trying to migrate parts of a Windows Service into the AKKA.net actor model however when it comes to DI for the actors (they have some dependencies such as data access layer, etc.) I'm having a bit of a problem because I don't fully understand how to wire up the DependencyResolver in the service. If that was a web application then it would be DependencyResolver of the HttpConfiguraiton however in this case I currently have the standard kernel to do the bootstrapping and get the top level interface implementacion to start the Windows Service.
I would have then two questions:
I have been reading here: http://getakka.net/docs/Dependency%20injection#ninject
Thanks in advance!
I'm using Akka.NET in a windows service (with topshelf and autofac but this approach should work for any service runner and IoC framework). I start up the top level actor in the startup method of the service like so:
_scope.Resolve<ActorSystem>().ActorOf<MyTopLevelActor>().Tell(new StartMySystemMessage());
From there I create child actors with either
var actorWithoutDependencies = Context.ActorOf<ChildActorType>();
where the actor type has a default constructor, or
var actorWithDependencies = Context.ActorOfDI<ChildActorType>();
where the child actor type has dependencies.
The ActorOfDI calls are extension methods which I use to wrap the ActorSystem.DI() and IActorContext.DI() methods in akka.net as follows:
public static IActorRef ActorOfDI<T>(this ActorSystem actorSystem, string name = null) where T : ActorBase
{
return actorSystem.ActorOf(actorSystem.DI().Props<T>(), name);
}
public static IActorRef ActorOfDI<T>(this IActorContext actorContext, string name = null) where T : ActorBase
{
return actorContext.ActorOf(actorContext.DI().Props<T>(), name);
}
In terms of IoC configuration for the actors, I'm registering all actor types in the assemblies containing the actors (using Autofac) as follows:
containerBuilder.RegisterAssemblyTypes(typeof(SomeActorType).Assembly).Where(x => x.Name.EndsWith("Actor"));
and to register the actor system itself I'm doing this:
containerBuilder.Register(c =>
{
var system = ActorSystem.Create("MyActorSystem");
// ReSharper disable once ObjectCreationAsStatement
new AutoFacDependencyResolver(lazyContainer.Value, system);
return system;
}).As<ActorSystem>().SingleInstance();
where lazyContainer is a:
Lazy<IContainer> // this is an autofac type
and the constructor delegate calls
containerBuilder.Build() // this is an autofac call
To get the actor system from within another dependency injected class you can then just pass an ActorSystem into the constructor for the class. I'm not sure about getting a reference to the system actor in my application code - I haven't needed to do that myself.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With