Plugins let you register handlers that help initialize an actor upon start up. We are currently using this for the Stashing support.
Instead of providing AbstractUntypedStashedActor, AbstractTypedStashedActor, AbstractYaddaYaddaStashedActor etc. (F# versions etc) We can instead apply an interface to the actor type, and let the framework inject extra state holders and such. it's sort of a poor mans Mixins
Dependency injection is implemented as a System plugin.
Our design is based on the fact that .NET has the IDisposable interface for cleaning up expensive resources.
Some DI frameworks supports this, and thus, if we use such framework from within Akka.NET, we also need to call back to the DI framework, notifying it that an actor is terminated.
Async language support is present in both C# and F#. Our current implementation is experimental and supports two different flavors:
-
Non-reentrant, this means the true actor model semantics is preserved, only one message can be processed at a time. The behavior is the same as in the synchronous world, but non blocking.
-
Reentrant, this does not mean reentrant in parallel, it is reentrant concurrently. That is, while there is a pending "await" section, other messages can be processed. messages are multiplexed on the actor. This means that you can get odd state changes during a long running async await block.
We did originally stay true to all the Akka primitives, e.g. ActorRef
But due to community request, All interfaces in Akka.NET has been prefixed with "I", which is idiomatic in .NET land.
Yay for our herritage from hungarian notation.
We have a special type of actor that gives us pattern match like features in C#
public class MyActor : ReceiveActor
{
public MyActor()
{
Receive<Foo>(foo => do stuff with foo);
Receive<string>(str => Console.WriteLine(str));
}
}This have become our default actor for C# as matching messages in the UntypedActor needs to do type checks, e.g. `if (msg is Foo){ }´ + a lot of type casting.