What is Xamarin ?

xamagonSeveral months ago I wrote an article to share my experience of a web developer moving to the world of mobile applications development. I am working in this field using the Xamarin technology. And you might have heard that Microsoft just acquired Xamarin, but I will not speak about this topic in this blog post, I do not have any opinion at the moment regarding this news.

When I introduce myself as a Xamarin developer, I often have to explain what it means even to other developers. And this is why I am creating this blog post, to introduce not only the technology but also the entire platform.

The technology

“Oh, I see, it’s like Cordova” is an answer I get from time to time, which is a start. Well, if you imply that Xamarin helps building cross-platform mobile applications, it is correct, but it is not really “like” Cordova.

What I like with Xamarin is the fact that it allows me to create native applications like an Android or iOS developer would do. The only difference is that I do not use the same programming language, instead of Java/Kotlin or Objective-C/Swift, I use C#. Like an Android developer I deal with activities, fragments, intents, AXML files and like an iOS developer I use storyboards, view controllers, UIView controls…

So, if the only difference is the programming language, what is the advantage of using Xamarin? Well, if you develop a mobile application on only one platform it might not be very interesting to use it except if you only know C#. But if you create an application on several platforms, it becomes relevant, because you can share code between Android, iOS and Windows Phone for instance. All of your apps use the same programming language. For example you can create a library with a API client for you application and use it on Android, iOS and Windows Phone: write it once and use it three times.

It is also possible to use Xamarin.Forms to share code between the User Interface (UI) for the three platforms I previously mentioned. But I will not go into the details because I have not used this technology at the moment. I can only tell you that it used a similar XAML format than the one available on the Windows platform.

The tools

“But how do I write C# with Xcode?” You cannot, to develop mobile applications with C#, Xamarin provides an Integrated Development Environment (IDE) called Xamarin Studio which is available on Mac OS and Windows. You can also use a Visual Studio plugin to create Android and iOS apps from Windows, but keep in mind that you will still need a Mac for iPhone/iPad to be able to build and for the simulator.

Xamarin also provides their own Android simulator to test and debug android applications: the Xamarin Android Player, which is pretty good and available on Windows and Mac.

You can also monitor your applications with the Xamarin Profiler (still in preview at the moment) in order to track the memory allocations and to find potential memory leaks. It also allows to track time and to find bottlenecks. I used it to review the memory usage of an existing application and I was able to detect several anomalies easily, it is a very helpful tool.

The services

Xamarin not only provide tools to help us developing cross-platform applications, it also offers several services to improve the overall experience. Learning mobile apps development can be overwhelming at first, especially when you try to learn several platforms at the same time. The Xamarin University aims to help you in this matter, but it clearly targets organization and not individuals (it is expensive).

Xamarin also offers a cloud platform in order to test your applications on a lot of different devices: Xamarin Test Cloud. You can access more smartphones configurations than you will ever be able to get, you will be able to detect issues related to a specific OS version.

Once your applications is released you might want to monitor what is going on, is it stable? What are the errors my clients encountered? What the users do with the application? To answer these questions you can use the Xamarin Insights services. It will give you access to a dashboard allowing you to see a lot of useful information for your applications. But you will have to use the SDK and “plug it” inside your code base. So you have to plan it before your release if you want to use it, it is not something you just activate afterward.

Here is my introduction of the Xamarin platforms, I hope this helps you to gain a better understanding of what is Xamarin and what are the tools and services available with it. Xamarin is not just a technology it is also an entire ecosystem available to the developers who want to create native applications. You also have to keep in mind that some of these products might change in the future depending on the strategy of Microsoft for the entire Xamarin platform.

See you next time !

AkkaOfEmpires: Dependency Injection with Akka.DI

akkadotnet-logoIn my last AkkaOfEmpires blog post, I started to use dependency injection (DI) for my various actors, but it was made “by hand”. So today I will show how to do it with Akka.DI, which is a plugin bringing DI to Akka.NET.

My goal is to be able to ask the actor system for VillagerActor instances without having to specify their dependencies, I’ll let Akka.DI handle this job.

Here is the VillagerActor constructor having the dependencies:

public VillagerActor(IActorRef resourcesSupervisor, SubroutinesFactory subroutinesFactory)
{
    _resourcesSupervisor = resourcesSupervisor;
    _subroutinesFactory = subroutinesFactory;
    Profession = Profession.Idle;
}

And here is the use case:

// Program.cs
var system = AkkaOfEmpiresSystem.Start();
 
var supervisorProps = Props.Create<ConsoleResourcesSupervisorActor>();
var supervisor = system.ActorOf(supervisorProps);
 
var consoleSubroutinesFactory = new ConsoleSubroutinesFactory();
var villagerProps = Props.Create<ConsoleVillagerActor>(supervisor, consoleSubroutinesFactory);
var gatherer = system.ActorOf(villagerProps, "Gatherer");
gatherer.Tell(new GatherFruits());

Using Akka.DI

Now I will change this last part in order to use dependency injection. First there is a nuget to install, in my case I will use StructureMap for the Inversion of Control (IoC) container.

Install-Package Akka.DI.StructureMap

Now, if you want to use another one you can see the list of available Akka.DI extensions here.

First I will rework the SubroutinesFactory by extracting an interface.

public interface ISubroutinesFactory
{
    IActorRef CreateResourceHarvesterActor(IActorContext actorContext, IActorRef villagerActor);
}
 
public class SubroutinesFactory : ISubroutinesFactory
{
    public IActorRef CreateResourceHarvesterActor(IActorContext actorContext, IActorRef villagerActor)
    {
        var props = Props.Create<ResourceHarvesterActor>(actorContext.System.Scheduler, villagerActor);
        var resourceHarvesterRoutine = actorContext.ActorOf(props);
        return resourceHarvesterRoutine;
    }
}
 
public class ConsoleSubroutinesFactory : ISubroutinesFactory
{
    public IActorRef CreateResourceHarvesterActor(IActorContext actorContext, IActorRef villagerActor)
    {
        var props = Props.Create<ConsoleResourceHarvesterActor>(actorContext.System.Scheduler, villagerActor);
        var consoleActor = actorContext.ActorOf(props);
        return consoleActor;
    }
}

Like before, I have two factories: a “classic” one and another one for the Console GUI. I will use the latter in my DI configuration.

Akka.DI uses a dependency resolver to link the IoC container with the actor system, there is one avaialble in the nuget package. I can now update the code:

// Program.cs
static void Main(string[] args)
{
    var system = AkkaOfEmpiresSystem.Start();
    var container = GetDependencyContainer();
    var resolver = new StructureMapDependencyResolver(container, system);
 
    var villagerProps = system.DI().Props<ConsoleVillagerActor>();
    var gatherer = system.ActorOf(villagerProps);
    gatherer.Tell(new GatherFruits());
 
    system.AwaitTermination();
}
 
static IContainer GetDependencyContainer()
{
    var container = new Container(c =>
    {
        c.For<ISubroutinesFactory>().Use<ConsoleSubroutinesFactory>();
    });
    return container;
}

I have specified that every instance of ISubroutinesFactory will be automatically resolved as ConsoleSubroutinesFactory instances and that is what will happen when requesting a new VillagerActor from the system.

I have taken care of one of the two dependencies for the actor. The other one is tricky because it is a IActorRef instance which can refer to every type of actor in the system.

The easy way

Well, at the moment the only IActorRef I need to inject through DI is for the ResourcesSupervisorActor, so I can have the following workaround:

static void Main(string[] args)
{
    var system = AkkaOfEmpiresSystem.Start();
    var container = GetDependencyContainer(system);
    var resolver = new StructureMapDependencyResolver(container, system);
 
    var villagerProps = system.DI().Props<ConsoleVillagerActor>();
    var gatherer = system.ActorOf(villagerProps);
    gatherer.Tell(new GatherFruits());
 
    system.AwaitTermination();
}
 
static IContainer GetDependencyContainer(ActorSystem system)
{
    var container = new Container(c =>
    {
        c.For<ISubroutinesFactory>().Use<ConsoleSubroutinesFactory>();
        c.ForSingletonOf<IActorRef>().Use(system.ActorOf<ConsoleResourcesSupervisorActor>());
    });
    return container;

I defined the dependency as a singleton because I want the resources supervisor to be the same for all the villagers. But now every classes that will need a IActorRef dependency will have a supervisor actor when constructed through DI.

With some IoC containers it is possible to play with named instance and conditions over the constructor parameters to provide the correct instance. But… meh… it is painful to set up and I think it can be dangerous. Let’s try something else.

Another way

What I can also do to fix my problem is removing the dependency to the IActorRef. Instead I will inject a service that will provide the reference to the supervisor actor, like I did for the subroutine actor.

public interface ISupervisorsFactory
{
    IActorRef GetResourcesSupervisor();
}
 
public class SupervisorsFactory : ISupervisorsFactory
{
    public SupervisorsFactory(ActorSystem system)
    {
        _resourcesSupervisor = system.ActorOf<ResourcesSupervisorActor>();
    }
 
    private readonly IActorRef _resourcesSupervisor;
 
    public IActorRef GetResourcesSupervisor()
    {
        return _resourcesSupervisor;
    }
}
 
public class ConsoleSupervisorsFactory : ISupervisorsFactory
{
    public ConsoleSupervisorsFactory(ActorSystem system)
    {
        _resourcesSupervisor = system.ActorOf<ConsoleResourcesSupervisorActor>();
    }
 
    private readonly IActorRef _resourcesSupervisor;
 
    public IActorRef GetResourcesSupervisor()
    {
        return _resourcesSupervisor;
    }
}

Now this factory can be used by the VillagerActor like this:

public VillagerActor(ISupervisorsFactory supervisorsFactory, ISubroutinesFactory subroutinesFactory)
{
    _resourcesSupervisor = supervisorsFactory.GetResourcesSupervisor();
    _subroutinesFactory = subroutinesFactory;
    Profession = Profession.Idle;
}

And I can update my IoC container configuration to link everything.

static IContainer GetDependencyContainer(ActorSystem actorSystem)
{
    var container = new Container(c =>
    {
        c.For<ISubroutinesFactory>().Use<ConsoleSubroutinesFactory>();
        c.ForSingletonOf<ISupervisorsFactory>()
            .Use<ConsoleSupervisorsFactory>()
            .Ctor<ActorSystem>()
            .Is(actorSystem);
    });
    return container;
}

Here is the end of my introduction to Akka.DI for Akka.NET. It allows the instantiation of actor references without having to declare all their dependencies every time a new actor is needed. Yet using DI with Akka.NET can become tricky when these dependencies are others IActorRef. At the moment I prefer avoiding them as much as possible.

Feel free to share your own experience with Akka.DI when it comes to IActorRef.

See you next time!

Async-Await and the UI thread

frozen-computerA few weeks ago I shared my experience of moving from web development to mobile development. In this article I mentioned asynchronous programming which is mandatory for desktop and mobile applications.

Today I will give you an example to demonstrate how to use the async-await pattern in order to avoid having a User Interface (UI) that freezes (does not respond to user interaction).

The synchronous approach

In this demo, I have created a simple WPF application with a button and a label, I will not use the Model-View-ViewModel (MVVM) pattern in this example. When clicking on the button some data will be retrieved on a repository and processed by a service before updating the label with the value.

main-window

Here is the XAML for this window:

<Window x:Class="AsyncAwait.WPF.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:AsyncAwait.WPF"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Button x:Name="button" Content="Button" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Width="497" Click="button_Click"/>
        <Label x:Name="label" Content="Label" HorizontalAlignment="Left" Margin="10,45,0,0" VerticalAlignment="Top" Width="497"/>
    </Grid>
</Window>

And the C# code can be found below.

// MainWindow.xaml.cs
public partial class MainWindow : Window
{
    public MainWindow()
    {
        _domainService = new DomainService();
        InitializeComponent();
    }
 
    private readonly DomainService _domainService;
 
    private void button_Click(object sender, RoutedEventArgs e)
    {
        var labelData = _domainService.GetData();
        this.label.Content = labelData;
    }
}
 
// DomainService.cs
public class DomainService
{
    public DomainService()
    {
        _dataRepository = new DataRepository();
    }
 
    private readonly DataRepository _dataRepository;
 
    public string GetData()
    {
        var data = _dataRepository.RetrieveData();
        data = ComputeData(data);
        return data;
    }
 
    private string ComputeData(string data)
    {
        Thread.Sleep(5000); // mocking calculation latency
        return data.ToUpper();
    }
}
 
// DataRepository.cs
public class DataRepository
{
    public string RetrieveData()
    {
        return RetrieveDataInternal();
    }
 
    private string RetrieveDataInternal()
    {
        Thread.Sleep(5000); // mocking latency
        return "my data";
    }
}

I used the Thread.Sleep() method to mock latency, due to database/network access and calculation time.

From a syntax point of view the code compile and does what it needs to do. But when we launch this program, the UI will freeze for 10 seconds and will not respond to the user interactions. This clearly not the best experience for a software.

The application has this behavior because all the work is done on the UI thread and it won’t be able to do its main work: displaying and refreshing the UI (responding to the user inputs is part of it).

It is time to update the code to make the code asynchronous.

Using Async-Await

I refactored the previous code to be able to use the async and await keywords.

// MainWindow.xaml.cs
public partial class MainWindow : Window
{
    public MainWindow()
    {
        _domainService = new DomainService();
        InitializeComponent();
    }
 
    private readonly DomainService _domainService;
 
    private async void button_Click(object sender, RoutedEventArgs e)
    {
        try
        {
            var labelData = await _domainService.GetDataAsync();
            this.label.Content = labelData;
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }
}
 
// DomainService.cs
public class DomainService
{
    public DomainService()
    {
        _dataRepository = new DataRepository();
    }
 
    private readonly DataRepository _dataRepository;
 
    public async Task<string> GetDataAsync()
    {
        var data = await _dataRepository.RetrieveDataAsync();
        data = ComputeData(data);
        return data;
    }
 
    private string ComputeData(string data)
    {
        Thread.Sleep(5000); // mocking calculation latency
        return data.ToUpper();
    }
}
 
// DataRepository.cs
public class DataRepository
{
    public Task<string> RetrieveDataAsync()
    {
        return RetrieveDataInternalAsync();
    }
 
    private Task<string> RetrieveDataInternalAsync()
    {
        Thread.Sleep(5000);
        return Task.FromResult("my data");
    }
}

Great! It should be better this way, let’s try it… It still freeze for 10 seconds… Even with the async-await pattern!

That is normal, the program does not create a Task on a separate thread and therefore all the code is still executed on the UI thread. Only using the async/await keywords is not enough to make the code asynchronous. Some methods of the .NET framework will create tasks on separate thread to allow you to use this pattern, like the GetAsync() method of the HttpClient class (see more examples here). You can detect them by looking at the “Async” suffix in the method name, it is a convention to use this suffix to notify calling code that the method is “awaitable”.

In my case I will fix my problem by creating a new Task with the Task.Run() method:

// DataRepository.cs
private Task<string> RetrieveDataInternalAsync()
{
    return Task.Run(() =>
    {
        Thread.Sleep(5000); // mocking latency
        return "my data";
    });
}

This gives me a Task I can use in my class hierarchy to run the code asynchronously. Now if we run the program it is better but the UI will still freeze for about 5 seconds…

This is caused by the ComputeData() method in the DomainService class which is executed on the UI thread. Well, I can use another Task.Run() to solve this problem. True but I can also use another feature of the Task to solve my issue: Task.ConfigureAwait():

// DomainService.cs
public async Task<string> GetDataAsync()
{
    var data = await _dataRepository.RetrieveDataAsync().ConfigureAwait(false);
    data = ComputeData(data);
    return data;
}

The parameter of the ConfigureAwait method (named “continueOnCaptureContext”) allows us to specify if we want that the rest of the method to executed on the captured context or not. This refers to the calling thread which is the UI thread in my case. By default this value is set to true and that means that the ComputeData() method was executed on the UI thread which explains why the application froze.

Now, if we run the application, the label will still be updated after 10 seconds but the Window will be responding to the user interactions which is, in my opinion way better for the user experience.

This ConfigureAwait tip looks great, let me use it on the button_Click() method!

// MainWindow.xaml.cs
private async void button_Click(object sender, RoutedEventArgs e)
{
    try
    {
        var labelData = await _domainService.GetDataAsync().ConfigureAwait(false);
        this.label.Content = labelData;
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

But when I run the program, I have the following result:

main-window-failed

I have an InvalidOperationException with the following message: “The calling thread cannot access this object because a different thread owns it”, displayed in a message box (in French in my case due to my configuration).

This error happens because I try to access the label property of the MainWindow from a thread different from the UI one. This is caused by the ConfigureAwait(false) I put, in this case I don’t want it because the code needs to be executed on the captured context.

Conclusion

Working with the async/await pattern needs practice to be understood, I wrote this article to explains some concepts of it by showing its impacts on a UI interface. I do not claim to be an expert on the subject, there is a lot more I need to learn on this topic. But remember that you need a Task to work with to unlock the potential of this pattern.

The Task.ConfigureAwait() method is also a powerful ally to lighten the work done by the UI thread but it needs to be used carefully to avoid invalid operations in the application.

The async keywork can only be used on methods returning a Task, a Task<T>, or void. This last case can be dangerous and should be avoided as much as possible, in my case the only async void method is the button_click event handler. I took care of encapsulating the whole code in a try/catch block and every time you see an async void method you should do it as well. Because it behaves as a “fire and forget” call and if you do not handle the exceptions in the method, they will be raise later without knowing exactly when or where and it will likely stop the process and the application.

I hope this example can help you if you are starting with asynchronous programming in C# .NET.

See you next time!


Image credits:

https://www.flickr.com/photos/netbooknews/

 

AkkaOfEmpires: Extending the GUI and actor factory

akkadotnet-logoIn my last AkkaOfEmpires blog entry I started a Graphic User Interface (GUI), only on console mode, to display how the actors in my system behave. In this project I use the Akka.NET framework (implementation of the actor model)  to re-create some of the rules present in Age of Empires II.

I was able to add a “console” implementation for two actors on the three I currently have in the system. This last actor is harder to “override” because its creation is done by another actor. Here is the code I am talking about (inside the VillagerActor):

var props = Props.Create<ResourceHarvesterActor>(Context.System.Scheduler, Self);
var resourceHarvesterRoutine = Context.ActorOf(props);

An I would like to use the following implementation of the ResourceHarvesterActor.

public class ConsoleResourceHarvesterActor : ResourceHarvesterActor
{
    public ConsoleResourceHarvesterActor(ITellScheduler messageScheduler, IActorRef villagerAcor)
        : base(messageScheduler, villagerAcor)
    {
    }
 
    public override void Handle(ResourceHarvested message)
    {
        base.Handle(message);
        Console.WriteLine("1 unit of {0} harvested. (carrying {1}).", ResourceToHarvest, CurrentlyCarrying);
    }
}

But, as I said in my last article, I cannot directly use this class in the VillagerActor, because it would create a circular reference and I don’t want to have “GUI” classes in my “core” project.

I think this issue shows that there is some coupling in the VillagerActor, indeed the class directly use the Props API and the Context. I believe it would be a good thing to extract this part of the code and encapsulate it in a dependency.

An actor factory

To fix this issue I will create a factory which will deal with the creation of the subroutine for the other actors and I will be able to use this class as a dependency for the VillagerActor. This way I will remove some coupling in the code.

Here is the factory:

public class SubroutinesFactory
{
    public virtual IActorRef CreateResourceHarvesterActor(IActorContext actorContext, IActorRef villagerActor)
    {
        var props = Props.Create<ResourceHarvesterActor>(actorContext.System.Scheduler, villagerActor);
        var resourceHarvesterRoutine = actorContext.ActorOf(props);
        return resourceHarvesterRoutine;
    }
}

The method in this factory needs some parameters to do its job, first an actor context in order to access the Scheduler and to create the IActorRef instance, secondly the IActorRef for the VillagerActor needing the subroutine.

I can now update my code to use this new class.

public class VillagerActor : ReceiveActor
{
    private readonly IActorRef _resourcesSupervisor;
    private readonly SubroutinesFactory _subroutinesFactory;
 
    public VillagerActor(IActorRef resourcesSupervisor, SubroutinesFactory subroutinesFactory)
    {
        _resourcesSupervisor = resourcesSupervisor;
        _subroutinesFactory = subroutinesFactory;
        //...
    }
 
    //...
 
    protected virtual void ResourceHarvester(IHarvestResourceCommand command)
    {
        //...
 
        var resourceHarvesterRoutine = _subroutinesFactory.CreateResourceHarvesterActor(Context, Self);
        resourceHarvesterRoutine.Tell(command);
 
        //...
    }
 
    //...
}

Override in the GUI

Now, the good thing is that I can create another implementation for this factory in my Console GUI project to use the ConsoleResourceHarvesterActor instead of the regular ResourceHarvesterActor.

public class ConsoleSubroutinesFactory : SubroutinesFactory
{
    public override IActorRef CreateResourceHarvesterActor(IActorContext actorContext, IActorRef villagerActor)
    {
        var props = Props.Create<ConsoleResourceHarvesterActor>(actorContext.System.Scheduler, villagerActor);
        var consoleActor = actorContext.ActorOf(props);
        return consoleActor;
    }
}

And now I can update my program in the GUI project to inject the implementation I want.

static void Main(string[] args)
{
    var system = AkkaOfEmpiresSystem.Start();
 
    var supervisorProps = Props.Create<ConsoleResourcesSupervisorActor>();
    var supervisor = system.ActorOf(supervisorProps);
 
    var consoleSubroutinesFactory = new ConsoleSubroutinesFactory();
    var villagerProps = Props.Create<ConsoleVillagerActor>(supervisor, consoleSubroutinesFactory);
    var gathered = system.ActorOf(villagerProps);
    gathered.Tell(new GatherFruits());
 
    system.AwaitTermination();
}

(To avoid too much flooding on the console I put only one villager instead of three).

And when launching the application, we can see the following output, letting us know what is happening.

AkkaOfEmpires-Second

We now have what we wanted, information is displayed for each actor and we have a pretty good idea of what is going on. The overall behavior looks good.

In this post I showed a way to extract the logic of creating an actor in a dependency in order to override the behavior, you can find the entire solution here.

For the moment my project is quite small and I only have two levels in my class hierarchy, therefore this “factory” fix will be hard to continue in the future because I have to inject the dependencies at the “boundaries” (the Main() method in my case). In the next AkkaOfEmpires post I will introduce Dependency Injection (DI) when working with Akka.NET to remove this future problem.

See you next time!

AkkaOfEmpires: Refactoring and First GUI

akkadotnet-logoToday, I will continue my journey with my project named AkkaOfEmpires. In this project I implement some of the rules of the game Age Of Empires II using the actor model with Akka.NET. You can find the last entries about the project here and here.

In this blog post I will not add new functionalities related to the game, first I feel the need to change a few things I made. I want to change the communication between the VillagerActor and the ResourceHarvesterActor routine. See the code for these two classes below.

Here is the VillagerActor:

public class VillagerActor : ReceiveActor
{
    private readonly IActorRef _resourcesSupervisor;
 
    public VillagerActor(IActorRef resourcesSupervisor)
    {
        _resourcesSupervisor = resourcesSupervisor;
        Profession = Profession.Idle;
 
        var props = Props.Create<ResourceHarvesterActor>(Context.System.Scheduler, _resourcesSupervisor);
        _resourceHarvesterRoutine = Context.ActorOf(props);
    }
 
    public Profession Profession { get; private set; }
    public Resource ResourceToRecolt { get; private set; }
 
    private readonly IActorRef _resourceHarvesterRoutine;
 
    protected override void PreStart()
    {
        base.PreStart();
        Become(Idle);
    }
 
    private void Idle()
    {
        ListenForCommands();
    }
 
    private void ResourceHarvester(IHarvestResourceCommand command)
    {
        Profession = command.AssociatedProfession;
        ResourceToRecolt = command.ResourceToRecolt;
 
        _resourceHarvesterRoutine.Tell(command);
 
        ListenForCommands();
    }
 
    private void ListenForCommands()
    {
        Receive<IHarvestResourceCommand>(m => Become(() => ResourceHarvester(m)));
    }
}

And theResourceHarvesterActor:

public class ResourceHarvesterActor : TypedActor,
    IHandle<IHarvestResourceCommand>,
    IHandle<ResourceHarvesterActor.ResourceHarvested>
{
    private readonly ITellScheduler _messageScheduler;
    private readonly IActorRef _resourcesSupervisor;
 
    public const uint MAX_CAPACITY = 10;
    public uint CurrentlyCarrying { get; private set; }
 
    public Resource ResourceToHarvest { get; private set; }
 
    public ResourceHarvesterActor(ITellScheduler messageScheduler, IActorRef resourcesSupervisor)
    {
        _messageScheduler = messageScheduler;
        _resourcesSupervisor = resourcesSupervisor;
        CurrentlyCarrying = 0;
    }
 
    public void Handle(IHarvestResourceCommand message)
    {
        if (message.ResourceToRecolt != ResourceToHarvest)
        {
            ResourceToHarvest = message.ResourceToRecolt;
            CurrentlyCarrying = 0;
        }
        _messageScheduler.ScheduleTellOnce(TimeSpan.FromSeconds(1), Self, new ResourceHarvested(), Self);
    }
 
    public void Handle(ResourceHarvested message)
    {
        CurrentlyCarrying++;
        if (CurrentlyCarrying == MAX_CAPACITY)
            _resourcesSupervisor.Tell(new ResourceGathered(ResourceToHarvest, CurrentlyCarrying));
        else
            _messageScheduler.ScheduleTellOnce(TimeSpan.FromSeconds(1), Self, new ResourceHarvested(), Self);
    }
 
    public class ResourceHarvested { }
}

Refactoring

What I don’t like with this code is the fact that the “routine” sends the message to the resources supervisor directly. In my opinion the routine should notify the VillagerActor when the capacity is reached and then stops its process.

For me this child actor should not be aware of any actor except itself and its parent. The higher level actor will take care of the communication with the supervisor.

Akka.NET does not provide any shortcut to send messages to the parent of an actor, therefore we will have to inject the reference. We already have a parameter in the constructor of type IActorRef, for the supervisor, from now it will be a reference to the VillagerActor. The type does not change but the actor at the other side of this reference will, then it is extremely important to use proper names when manipulating IActorRef references.

private readonly IActorRef _villagerActor;
 
public ResourceHarvesterActor(ITellScheduler messageScheduler, IActorRef villagerAcor)
{
    _messageScheduler = messageScheduler;
    _villagerActor = villagerAcor;
    CurrentlyCarrying = 0;
}

I now need to refactor the case when the maximum capacity is reached. The villagerActor will be notify and will behave accordingly and the routine will be stopped.

public virtual void Handle(ResourceHarvested message)
{
    CurrentlyCarrying++;
    if (CurrentlyCarrying == MAX_CAPACITY)
    {
        _villagerActor.Tell(new MaxCapacityReached(CurrentlyCarrying));
        Context.Stop(Self);
    }
    else
        _messageScheduler.ScheduleTellOnce(TimeSpan.FromSeconds(1), Self, new ResourceHarvested(), Self);
}

To do this, I created a new message type names MaxCapacityReached with the amount of resource gathered. And to stop the actor I use the Stop() method of the Context property with Self as argument. By doing so the actor system will stop the current instance of the actor.

Now I need to update the behavior of the VillagerActor to properly use the ResourceGathererActor.

protected virtual void ResourceHarvester(IHarvestResourceCommand command)
{
    _currentCommand = command;
    Profession = command.AssociatedProfession;
    ResourceToRecolt = command.ResourceToRecolt;
 
    var props = Props.Create<ResourceHarvesterActor>(Context.System.Scheduler, Self);
    var resourceHarvesterRoutine = Context.ActorOf(props);
    resourceHarvesterRoutine.Tell(command);
 
    ListenForCommands();
}

I moved the creation of the child actor (the usage of Props and Context) inside the method (it was in the constructor before), because now the routine actor will stop once its job is done. If this is not done, the program will not crash, instead the message will not be delivered and will become a “dead letter” (more information on JVM Akka website here). Note that I also save the received command in a field, which will be used shortly.

Now this VillagerActor also need a new handler for MaxCapacityReached message in order to “return to a depot” to increase the amount of resources available.

protected virtual void ResourceCarrier(uint quantity)
{
    _resourcesSupervisor.Tell(new ResourceGathered(ResourceToRecolt, quantity));
    Self.Tell();
    ListenForCommands();
}
 
private void ListenForCommands()
{
    Receive<IHarvestResourceCommand>(m => Become(() => ResourceHarvester(m)));
    Receive<MaxCapacityReached>(m => Become(() => ResourceCarrier(m.Quantity)));
}

Once the message has been sent to the ResourceSupervisorActor the VillagerActor will send itself the command it previously stored, this way it will continue its job by creating a new child actor (a routine) to gather resources.

Now the question is: Does that really work as expected? I could try to make some tests to cover these cases but I fear that they will be extremely difficult to write. Instead I think it is time for me to create the first GUI for the project. Do not get too excited, I will simply be a Console GUI…

The Console GUI

280px-Age_of_Empires_2_The_Age_of_Kings_LogoTo display the behaviors of the actors, I could simply add some Console.WriteLine() in the methods but I don’t want to pollute the code of my actors with this. Instead I will use inheritance to add this behavior.

To be able to do this, I have to change a few private methods and make them protected virtual (see in the code samples above). And I can now define some ConsoleActors in a new project (AkkaOfEmpires.ConsoleUI).

ConsoleResourcesSupervisorActor:

public class ConsoleResourcesSupervisorActor : ResourcesSupervisorActor
{
    public override void Handle(ResourceGathered message)
    {
        Console.WriteLine("ResourceGathered: {0} {1}", message.Quantity, message.ResourceType);
        base.Handle(message);
        Console.WriteLine("Resources available: {0}: {1} | {2}: {3} | {4}: {5} | {6}: {7}",
            Resource.Food, ResourcesAmounts[Resource.Food],
            Resource.Wood, ResourcesAmounts[Resource.Wood],
            Resource.Gold, ResourcesAmounts[Resource.Gold],
            Resource.Stone, ResourcesAmounts[Resource.Stone]);
    }
}

ConsoleVillagerActor:

public class ConsoleVillagerActor : VillagerActor
{
    public ConsoleVillagerActor(IActorRef resourcesSupervisor)
        : base(resourcesSupervisor)
    {
    }
 
    protected override void PreStart()
    {
        Console.WriteLine("A new villager appears!");
        base.PreStart();
    }
 
    protected override void ResourceHarvester(IHarvestResourceCommand command)
    {
        Console.WriteLine("Villager becomes {0}", command.AssociatedProfession);
        base.ResourceHarvester(command);
    }
 
    protected override void ResourceCarrier(uint quantity)
    {
        Console.WriteLine("Villager carries {0} {1}", quantity, ResourceToRecolt);
        base.ResourceCarrier(quantity);
    }
}

This way I am able to separate the “UI logic” from the message handling of the actors.

I have also created a static method creating the actor system (in the AkkaOfEmpires project this time):

public static class AkkaOfEmpiresSystem
{
    public static ActorSystem Start()
    {
        var system = ActorSystem.Create("AkkaOfEmpires");
 
        return system;
    }
}

And here is the Main program of the console application:

static void Main(string[] args)
{
    var system = AkkaOfEmpiresSystem.Start();
 
    var supervisorProps = Props.Create<ConsoleResourcesSupervisorActor>();
    var supervisor = system.ActorOf(supervisorProps);
 
    var villagerProps = Props.Create<ConsoleVillagerActor>(supervisor);
    var gathered = system.ActorOf(villagerProps);
    gathered.Tell(new GatherFruits());
 
    var shepherd = system.ActorOf(villagerProps);
    shepherd.Tell(new ShepherdFlock());
 
    var lumberjack = system.ActorOf(villagerProps);
    lumberjack.Tell(new CutTrees());
 
    system.AwaitTermination();
}

This program will create the resources supervisor actor and 3 villagers, the first will become a gatherer, the second a shepherd and the last a lumberjack. Now if we launched this program we have the following ouput (after about 50 seconds).

AkkaOfEmpires-First

Looks good, the food and wood amounts increase over time, these villagers are now efficient workers!

But… What about a ConsoleResourceHarvesterActor? Well, this one is a bit different, its creation is directly inside the VillagerActor and not in the program. I cannot used this specific actor in the code of the VillagerActor (Circular reference between AkkaOfEmpires and AkkaOfEmpires.ConsoleUI) and I do not want to, a UI class has nothing to do in my core project.

The resolution of this “issue” will be in my next AkkaOfEmpires blog post. Meanwhile you can take a look at the entire solution on GitHub.

See you next time!

Easy mocking with NSubstitute

NSubstitute logo
NSubstitute logo

Several months ago I introduced the concept of mocking dependencies of a class in order to ease the writing of tests for it. I also introduced the Moq library which is a mocking library and today I will introduced another one: NSubstitute. This project is open source and you can find it on GitHub.

I will not cover all the functionalities it offers, instead I will show you how it works with an example like I did with Moq. First you can install NSubstitute with Nuget:

Install-Package NSubstitute

What to test?

I have created the following service with a bit of logic to test.

public class NotificationService
{
    public NotificationService(IUserRepository userRepository, INotifier notifier, ILogger logger)
    {
        _userRepository = userRepository;
        _notifier = notifier;
        _logger = logger;
    }
 
    private readonly IUserRepository _userRepository;
    private readonly INotifier _notifier;
    private readonly ILogger _logger;
 
    public void NotifyUser(int userId)
    {
        User user;
        try
        {
            user = _userRepository.GetById(userId);
        }
        catch (Exception ex)
        {
            _logger.Error(ex.Message);
            return;
        }
        if (user.HasActivatedNotification)
        {
            _notifier.Notify(user);
        }
    }
}

This service relies on dependency injection to do its work, you’ll find these dependencies below.

public interface INotifier
{
    void Notify(User user);
}
 
public interface IUserRepository
{
    User GetById(int userId);
}
 
public interface ILogger
{
    void Error(string message);
}
 
public class User
{
    public bool HasActivatedNotification { get; set; }
}
 
public class InvalidUserIdException : Exception
{
    public override string Message
    {
        get { return "Given user ID is invalid"; }
    }
}

Let’s test it!

I will now write tests to cover the logic hold by the NotificationService class using NSubstitute. I will also use xUnit as testing framework, you can find more information about this project here.

In order to test the service we will have to instantiate it, and therefore we will have to inject the dependencies. So the first question is: how to create mock (or substitute) with NSubstitute? As a reminder it is done like this with Moq:

Mock<IUserRepository> mockRepository = new Mock<IUserRepository>();
IUserRepository repo = mockRepository.Object;

With NSubstitute the concept is similar but with one noticeable change.

IUserRepository userRepository = Substitute.For<IUserRepository>();

There is no wrapper for the mock, we directly manipulate an instance of the interface we want to substitute. You might wonder how to use it as a mock if it has only the methods defined in the interface, I’ll come to that later.

We can now setup our test class for the service with all the dependencies.

public class NotificationService_Should
{
    private readonly NotificationService _service;
 
    private readonly IUserRepository _userRepository;
    private readonly INotifier _notifier;
    private readonly ILogger _logger;
 
    public NotificationService_Should()
    {
        _userRepository = Substitute.For<IUserRepository>();
        _notifier = Substitute.For<INotifier>();
        _logger = Substitute.For<ILogger>();
 
        _service = new NotificationService();
    }
}

For information, the test setup is done in the class constructor with xUnit.

We can now focus on writing the first test for the class: verifying that the repository is called when executing the NotifyUser method. To do so we will use some extension methods provided by NSubstitute (here is the answer to the previous question).

[Fact(DisplayName = "NotifyUser calls the repository")]
public void Call_Repository()
{
    _service.NotifyUser(Arg.Any<int>());
    _userRepository.Received().GetById(Arg.Any<int>());
}

The Received() extension method checks that the following method is called. Since we don’t have to test for a particular user ID, we can use the Arg.Any<T>() method to specify that any integer is valid (with Moq it is It.IsAny<T>()). We run the test and…

Red-Test-Null

…it’s red? NullReferenceException… Of course! The mock repository does not return any instance of User and the execution fails after when trying to use the reference. Let’s fix this by configuring the substitute.

[Fact(DisplayName = "NotifyUser calls the repository")]
public void Call_Repository()
{
    _userRepository.GetById(Arg.Any<int>()).Returns(new User());
    _service.NotifyUser(1);
    _userRepository.Received().GetById(Arg.Any<int>());
}

Now the test is green, but in this test we setup a mock and then we test that it has been called, in my opinion it is not very constructive. We should try to focus on testing something else, the rest of the method’s logic depends on a property of the User, let’s test this for instance.

public NotificationService_Should()
{
    _userRepository = Substitute.For<IUserRepository>();
    _notifier = Substitute.For<INotifier>();
    _logger = Substitute.For<ILogger>();
 
    _service = new NotificationService(_userRepository, _notifier, _logger);
 
    _userRepository
        .GetById(Arg.Is<int>(i => i < 10))
        .Returns(new User { HasActivatedNotification = true });
    _userRepository
        .GetById(Arg.Is<int>(i => i >= 10))
        .Returns(new User { HasActivatedNotification = false });
}
 
[Fact(DisplayName = "NotifyUser calls notifier if user has activated the notifications")]
public void Call_Notifier_When_User_Has_Activated_Notification()
{
    _service.NotifyUser(1);
    _notifier.Received().Notify(Arg.Any<User>());
}
 
[Fact(DisplayName = "NotifyUser does not call notifier if user has not activated the notifications")]
public void Does_Not_Call_Notifier_When_User_Has_Not_Activated_Notification()
{
    _service.NotifyUser(11);
    _notifier.DidNotReceive().Notify(Arg.Any<User>());
}

This time I used the Arg.Is<T>() method to add condition to the substitute, this way I can setup the result of a method depending on some conditions. Here I set the HasActivatedNotification property to true if the userId is inferior to 10 and to false otherwise.

And to test that a method is not called I use the DidNotReceive() extension method. Now I will write a test for the case when an exception is thrown by the repository to check that the logger is correctly called.

public NotificationService_Should()
{
    _userRepository = Substitute.For<IUserRepository>();
    _notifier = Substitute.For<INotifier>();
    _logger = Substitute.For<ILogger>();
 
    _service = new NotificationService(_userRepository, _notifier, _logger);
 
    _userRepository
        .GetById(Arg.Is<int>(i => i < 10))
        .Returns(new User { HasActivatedNotification = true });
    _userRepository
        .GetById(Arg.Is<int>(i => i >= 10))
        .Returns(new User { HasActivatedNotification = false });
    _userRepository
        .GetById(Arg.Is<int>(i => i < 0))
        .Returns(user => { throw new InvalidUserIdException(); });
}
 
[Fact(DisplayName = "NotifyUser calls logger when an exception is thrown")]
public void Call_Logger_When_An_Exception_Is_Thrown()
{
    _service.NotifyUser(-1);
    _logger.Received().Error("Given user ID is invalid");
}

The service is now covered with tests thanks to the use of NSubstitute.

Green-Tests

This library offers more functionalities, you can find them on the documentation page of the project website.

As for me, I only discovered this library recently, I am more used to Moq. But I must say that I like the API offered by NSubstitute, I find it more “fluent”. I think it can be really helpful when doing Test Driven Development (TDD). I will definitely give it a shot for future projects.

Choosing a mocking library is important in order to write tests easily when using dependency injection and there is a lot of choice for this, Moq and NSubstitute are some of them. And you? What is your favorite library for mocking? What does it offer that others don’t have?

See you next time!

Akka.NET: Delegating work to child actors

akkadotnet-logoToday I will continue to present my work on AkkaOfEmpires, in this project I implement some of the rules from the game Age Of Empires II using the actor model with Akka.NET. You can have a look at the first step here.

In this last entry I introduced the concept of behavior switching using Akka.NET while providing an implementation for a villager (unit in the game) gathering various types of resources. In this article I will continue to work on the VillagerActor and I will mostly do refactoring.

280px-Age_of_Empires_2_The_Age_of_Kings_LogoFor the moment the villager has a dedicated method for all the professions he can have when gathering resource, see the class below.

public class VillagerActor : ReceiveActor
{
    private readonly IActorRef _resourcesSupervisor;
 
    public VillagerActor(IActorRef resourcesSupervisor)
    {
        _resourcesSupervisor = resourcesSupervisor;
        Profession = Profession.Idle;
    }
 
    public Profession Profession { get; private set; }
    public Resource ResourceToRecolt { get; private set; }
 
    protected override void PreStart()
    {
        base.PreStart();
        Become(Idle);
    }
 
    private void Idle()
    {
        CommandsHandler();
    }
 
    private void Gatherer()
    {
        Profession = Profession.Gatherer;
        ResourceToRecolt = Resource.Food;
        // repeat until new order or lack of bushes
        _resourcesSupervisor.Tell(new ResourceRecolted { ResourceType = ResourceToRecolt, Quantity = 10 });
 
        CommandsHandler();
    }
 
    private void Shepherd()
    {
        Profession = Profession.Shepherd;
        ResourceToRecolt = Resource.Food;
        // repeat until new order or lack of sheeps
        _resourcesSupervisor.Tell(new ResourceRecolted { ResourceType = ResourceToRecolt, Quantity = 10 });
 
        CommandsHandler();
    }
 
    private void Hunter()
    {
        Profession = Profession.Hunter;
        ResourceToRecolt = Resource.Food;
 
        _resourcesSupervisor.Tell(new ResourceRecolted{ResourceType = ResourceToRecolt, Quantity = 10});
 
        CommandsHandler();
    }
 
    private void Farmer()
    {
        Profession = Profession.Farmer;
        ResourceToRecolt = Resource.Food;
 
        _resourcesSupervisor.Tell(new ResourceRecolted { ResourceType = ResourceToRecolt, Quantity = 10 });
 
        CommandsHandler();
    }
 
    private void Fisherman()
    {
        Profession = Profession.Fisherman;
        ResourceToRecolt = Resource.Food;
 
        _resourcesSupervisor.Tell(new ResourceRecolted { ResourceType = ResourceToRecolt, Quantity = 10 });
 
        CommandsHandler();
    }
 
    private void Lumberjack()
    {
        Profession = Profession.Lumberjack;
        ResourceToRecolt = Resource.Wood;
 
        _resourcesSupervisor.Tell(new ResourceRecolted {ResourceType = ResourceToRecolt, Quantity = 10});
        CommandsHandler();
    }
 
    private void StoneMiner()
    {
        Profession = Profession.StoneMiner;
        ResourceToRecolt = Resource.Stone;
 
        _resourcesSupervisor.Tell(new ResourceRecolted { ResourceType = ResourceToRecolt, Quantity = 10 });
        CommandsHandler();
    }
 
    private void GoldMiner()
    {
        Profession = Profession.GoldMiner;
        ResourceToRecolt = Resource.Gold;
 
        _resourcesSupervisor.Tell(new ResourceRecolted { ResourceType = ResourceToRecolt, Quantity = 10 });
        CommandsHandler();
    }
 
    private void CommandsHandler()
    {
        Receive<GatherFruits>(m => Become(Gatherer));
        Receive<ShepherdFlock>(m => Become(Shepherd));
        Receive<HuntPrey>(m => Become(Hunter));
        Receive<FarmCrops>(m => Become(Farmer));
        Receive<CatchFish>(m => Become(Fisherman));
        Receive<CutTrees>(m => Become(Lumberjack));
        Receive<MineStone>(m => Become(StoneMiner));
        Receive<MineGold>(m => Become(GoldMiner));
    }
}

As you can see the code is quite redundant and there is already a lot of methods for the class. Yet a villager can do a lot more than simply gathering resource and I fear that my class will become too big. When working with Object Oriented Programming (OOP) I try to follow the SOLID principles and I feel like I’m starting to break the Single Responsibility Principle.

My goal is to create a child actor for the VillagerActor to deal with all the resource gathering to avoid having too much logic inside this class. But first I will do some refactoring.

Refactoring phase

You may have noticed that all the commands related to the resource gathering are similar, they are associated to a type of resource and to a profession, it looks like a good opportunity to introduce an interface for all of these commands.

public interface IHarvestResourceCommand
{
    Resource ResourceToRecolt { get; }
    Profession AssociatedProfession { get; }
}
 
public abstract class HarvestFood : IHarvestResourceCommand
{
    public Resource ResourceToRecolt
    {
        get { return Resource.Food; }
    }
 
    public abstract Profession AssociatedProfession { get; }
}
 
public abstract class HarvestWood : IHarvestResourceCommand
{
    public Resource ResourceToRecolt
    {
        get { return Resource.Wood; }
    }
 
    public abstract Profession AssociatedProfession { get; }
}
 
public abstract class HarvestGold : IHarvestResourceCommand
{
    public Resource ResourceToRecolt
    {
        get { return Resource.Gold; }
    }
 
    public abstract Profession AssociatedProfession { get; }
}
 
public abstract class HarvestStone : IHarvestResourceCommand
{
    public Resource ResourceToRecolt
    {
        get { return Resource.Stone; }
    }
 
    public abstract Profession AssociatedProfession { get; }
}

And now each command can inherit from the correct abstract class and just have to provide the profession associated to it (see some examples below).

public class FarmCrops : HarvestFood
{
    public override Profession AssociatedProfession
    {
        get { return Profession.Farmer; }
    }
}
 
public class CatchFish : HarvestFood
{
    public override Profession AssociatedProfession
    {
        get { return Profession.Fisherman; }
    }
}
 
public class CutTrees : HarvestWood
{
    public override Profession AssociatedProfession
    {
        get { return Profession.Lumberjack; }
    }
}
 
public class MineStone : HarvestStone
{
    public override Profession AssociatedProfession
    {
        get { return Profession.Miner; }
    }
}
 
public class MineGold : HarvestGold
{
    public override Profession AssociatedProfession
    {
        get { return Profession.Miner; }
    }
}

I can now update the implementation of the VillagerActor to use the properties available in the classes I just refactored to simplify it and to remove all the code duplication.

private void ResourceHarvester(IHarvestResourceCommand command)
{
    Profession = command.AssociatedProfession;
    ResourceToRecolt = command.ResourceToRecolt;
 
    _resourcesSupervisor.Tell(new ResourceRecolted { ResourceType = ResourceToRecolt, Quantity = 10 });
 
    ListenForCommands();
}
 
private void ListenForCommands()    // previously CommandsHandler()
{
    Receive<IHarvestResourceCommand>(m => Become(() => ResourceHarvester(m)));
}

In my opinion this is way cleaner than before even if the notion of one method by profession has been removed, we still have a property for this.

Now I think that I have a good base to add the child actor which will have a bit more logic than this current implementation.

The child actor

In Age Of Empires II, gathering resource takes time, a villager harvests resource one by one and brings them back to the a resource depot when his capacity is full. I will implement this logic in the new child actor called ResourceHarvesterActor. This actor is not a unit on its own, it will represent a subroutine of the villager.

public class ResourceHarvesterActor : TypedActor,
    IHandle<IHarvestResourceCommand>,
    IHandle<ResourceHarvesterActor.ResourceHarvested>
{
    private readonly ITellScheduler _messageScheduler;
    private readonly IActorRef _resourcesSupervisor;
 
    public const uint MAX_CAPACITY = 10;
    public uint CurrentlyCarrying { get; private set; }
 
    public Resource ResourceToHarvest { get; private set; }
 
    public ResourceHarvesterActor(ITellScheduler messageScheduler, IActorRef resourcesSupervisor)
    {
        _messageScheduler = messageScheduler;
        _resourcesSupervisor = resourcesSupervisor;
        CurrentlyCarrying = 0;
    }
 
    public void Handle(IHarvestResourceCommand message)
    {
        if (message.ResourceToRecolt != ResourceToHarvest)
        {
            ResourceToHarvest = message.ResourceToRecolt;
            CurrentlyCarrying = 0;
        }
        _messageScheduler.ScheduleTellOnce(TimeSpan.FromSeconds(1), Self, new ResourceHarvested(), Self);
    }
 
    public void Handle(ResourceHarvested message)
    {
        CurrentlyCarrying++;
        if (CurrentlyCarrying == MAX_CAPACITY)
            _resourcesSupervisor.Tell(new ResourceGathered { Quantity = CurrentlyCarrying, ResourceType = ResourceToHarvest });
        else
            _messageScheduler.ScheduleTellOnce(TimeSpan.FromSeconds(1), Self, new ResourceHarvested(), Self);
    }
 
    public class ResourceHarvested { }
}

To simulate the game logic, this actor will send a message to itself every second to increment the amount of resource the villager is carrying. To do so I use the ITellScheduler interface which is available in Akka.NET. This allows to set a delay before sending a message to an actor, in this case the actor is itself so I use the Self property. I chose to use this interface instead of an implementation to be able to inject the dependency to ease the testability of the class.

I also added a condition to detect when the villager is at full capacity, when it occurs then the ResourceSupervisorActor is used to increment the global counter for the resource being harvested (in the game the villager goes to the depot for this).

There is another game rule I implemented in this actor, the fact that a villager cannot gather several types a resource at the same time. For example if a lumberjack is ordered to go fishing, then the wood he is carrying is lost. I made a unit test to cover this case:

[Fact(DisplayName = "ResourceHarvesterActor Should Empty CurrentlyCarrying If Different Resource To Harvest")]
public void Empty_CurrentlyCarrying_If_Different_Resource_To_Harvest()
{
    _harvester.Tell(VillagerOrders.CutTrees);
    _harvester.Tell(new ResourceHarvesterActor.ResourceHarvested());
    _harvester.UnderlyingActor.CurrentlyCarrying.ShouldBe<uint>(1);
    _harvester.Tell(VillagerOrders.CatchFish);
    _harvester.UnderlyingActor.CurrentlyCarrying.ShouldBe<uint>(0);
}

Now I will use this new actor inside the VillagerActor.

public class VillagerActor : ReceiveActor
{
    private readonly IActorRef _resourcesSupervisor;
 
    public VillagerActor(IActorRef resourcesSupervisor)
    {
        _resourcesSupervisor = resourcesSupervisor;
        Profession = Profession.Idle;
 
        var props = Props.Create<ResourceHarvesterActor>(Context.System.Scheduler, _resourcesSupervisor);
        _resourceHarvesterRoutine = Context.ActorOf(props);
    }
 
    public Profession Profession { get; private set; }
    public Resource ResourceToRecolt { get; private set; }
 
    private readonly IActorRef _resourceHarvesterRoutine;
 
    protected override void PreStart()
    {
        base.PreStart();
        Become(Idle);
    }
 
    private void Idle()
    {
        ListenForCommands();
    }
 
    private void ResourceHarvester(IHarvestResourceCommand command)
    {
        Profession = command.AssociatedProfession;
        ResourceToRecolt = command.ResourceToRecolt;
 
        _resourceHarvesterRoutine.Tell(command);
 
        ListenForCommands();
    }
 
    private void ListenForCommands()
    {
        Receive<IHarvestResourceCommand>(m => Become(() => ResourceHarvester(m)));
    }
}

There is nothing particular in here except the fact that I used the Scheduler from the System (available through the Context) for the child actor. With the refactoring and the adding of a child actor, the VillagerActor has more the role of a coordinator than an actor since I remove all the logic from it. But this is a temporary situation, since I still have a lot of rules to implement, with time it will become a high level actor delegating work to child actors.

The code for the entire solution is available on my GitHub repository, it will allow you to see the entire project. Since I write the blog posts in parallel of the development of the solution itself it is likely that the code will change a lot with time due to constant refactoring. So it is possible that the code shown in the articles is not up-to-date when you read it, therefore do not hesitate the browse the changes in the repository’s history and to have a look at the different branches.

See you next time!