Using Akka.Templates to Create New Projects
6 minutes to readAkka.NET Word Counter 2
In Unit-0 we created a new project using the default console
project type via dotnet new
- in Unit-1 we’re going to create a new version of our “word counter” application from before with some additional capabilities:
- Ability to count words off of multiple web pages;
- Can aggregate word counts across documents; and
- Can provide incremental progress reports as it works.
This will allow us to continue our Akka.NET education and get exposed to some more real-world questions such as:
- Handle
Task<T>
s inside actors; - Run multiple actor workloads in parallel - and make sure the right message is received by the right actors;
- Create finite state machines using switchable behaviors;
- Leverage
IWithTimers
to schedule recurring messages and time-outs to actors; and - Use
ReceiveTimeout
to terminate idle actors, a popular technique for bounding memory consumption with actors; - How to integrate actors with the Microsoft.Extensions ecosystem for configuration, logging, hosting, dependency injection, and more.
- Unit testing our actors with the Akka.TestKit and the Akka.Hosting.TestKit.
Let’s get started.
Getting Help with Unit-1
If you get stuck at any point during these coding exercises, please refer to the Unit-1 source code on https://github.com/petabridge/akka-bootcamp/
You can also try the #akkadotnet-bootcamp
channel in the Akka.NET Discord and ask questions there.
Installing Akka.Templates
The first thing we’re going to do is install Akka.Templates
, a set of open source dotnet new
templates maintained by the Akka.NET project.
If you’ve never installed a
dotnet new
template before, you can learn more about them here: https://github.com/dotnet/templating/.
dotnet new install "Akka.Templates::*"
This will install the Akka.Templates
package from NuGet or update you to using the latest version of the package if you had an older one installed previously.
Any template you install for the dotnet
CLI will usually also work for IDEs like Visual Studio, VS Code, and JetBrains Rider - so these templates will create either new project / solution / code item options inside the menus for those IDEs as well.
Create a New Akka.Templates
Project
We’re going to use the akka.console
template as the foundation of our new “word counter 2” project.
akka.console
is a project
template, so in order to make it easy for us to add things like unit tests we’re going to create a .sln
file first.
Execute the following in your shell:
dotnet new sln -n "AkkaWordCounter2"
dotnet new akka.console -n "AkkaWordCounter2.App"
dotnet sln add AkkaWordCounter2.App
dotnet build
Not the world’s most creative name, but whatever, that’s what we’re rolling with.
You should see the following structure in the directory where you ran your command:
.
├── AkkaWordCounter2.App
│ ├── AkkaWordCounter2.App.csproj
│ ├── HelloActor.cs
│ ├── Program.cs
│ ├── README.md
│ ├── TimerActor.cs
│ ├── Usings.cs
└── AkkaWordCounter2.sln
Exploring the Template Output
Open the solution and then look at AkkaWordCounter2.App\Program.cs
. What did the template make for us?
using Akka.Hosting;
using AkkaWordCounter2;
using Microsoft.Extensions.Hosting;
var hostBuilder = new HostBuilder();
hostBuilder.ConfigureServices((context, services) =>
{
services.AddAkka("MyActorSystem", (builder, sp) =>
{
builder
.WithActors((system, registry, resolver) =>
{
var helloActor = system.ActorOf(Props.Create(() => new HelloActor()), "hello-actor");
registry.Register<HelloActor>(helloActor);
})
.WithActors((system, registry, resolver) =>
{
var timerActorProps =
resolver.Props<TimerActor>(); // uses Msft.Ext.DI to inject reference to helloActor
var timerActor = system.ActorOf(timerActorProps, "timer-actor");
registry.Register<TimerActor>(timerActor);
});
});
});
var host = hostBuilder.Build();
await host.RunAsync();
So this is a very different looking setup than what we saw in Unit-0! Where’s the ActorSystem.Create
and what are all of these WithActors
calls?
This is Akka.Hosting - Akka.NET’s “Pit of Success” for making sure customers handle application lifetimes, dependency injection, Microsoft.Extensions integration, and more correctly without too much trouble. We’re going to learn Akka.Hosting by using it throughout this sample.
What this code does:
- Starts the the
HelloActor
and registers it with theActorRegistry
; - Starts the
TimerActor
using Akka.DependencyInjection (because it has arguments injected into its constructor); and - Uses Microsoft.Extensions.Hosting to manage the lifetime of the
ActorSystem
- this is all handled automatically through a background service that gets started as part of theIServiceCollection.AddAkka
extension method.
We’re going to get into this componentry as we go through the lessons. For now, let’s move onto designing our actor hierarchy and messages for AkkaWordCounter2
.