When using the Receive actor API in Akka.NET, we can take advantage of overloads of the Receive method that allow us to specify predicates.
A message will now be handled if it is of the correct type and the predicate is met.
Take the following actor that sends emails with a different message if a customer is “high value”:
class WelcomeEmailSender : ReceiveActor
{
public WelcomeEmailSender()
{
Receive<SendNewCustomerWelcomeEmail>(message => HandleMessage(message));
}
private void HandleMessage(SendNewCustomerWelcomeEmail message)
{
if (message.IsHighValueCustomer)
{
SendEmail("Dear high value customer...", message.EmailAddress);
}
else
{
SendEmail("Yo! ...", message.EmailAddress);
}
}
private void SendEmail(string greeting, string emailAddress)
{
Console.WriteLine("{0} to {1}", greeting, emailAddress);
}
}
In the preceding code, the if statement is deciding what action is taken – the welcome message to be sent.
Using an overload of the receive method, we can add a predicate that replaces this if statement:
class WelcomeEmailSender2 : ReceiveActor
{
public WelcomeEmailSender2()
{
Receive<SendNewCustomerWelcomeEmail>(
message =>
{
SendEmail("Dear high value customer...", message.EmailAddress);
},
handleIf => handleIf.IsHighValueCustomer);
Receive<SendNewCustomerWelcomeEmail>(
message =>
{
SendEmail("Yo! ...", message.EmailAddress);
},
handleIf => handleIf.IsHighValueCustomer == false);
}
private void SendEmail(string greeting, string emailAddress)
{
Console.WriteLine("{0} to {1}", greeting, emailAddress);
}
}
In the preceding code the predicate (represented by the lambda: handleIf => handleIf.IsHighValueCustomer) replaces the if.
In these example we only have two possible predicates because we are looking at the boolean “IsHighValueCustomer”. The following code shows predicates being defined for non-boolean (string) values:
class SomeActor : ReceiveActor
{
public SomeActor()
{
Receive<string>(message => Console.WriteLine("Knock knock..."), handleIfMessage => handleIfMessage.Equals("Tell me a joke"));
Receive<string>(message => Console.WriteLine("Hello There!"), handleIfMessage => handleIfMessage.Equals("Say Hi"));
Receive<string>(message => Console.WriteLine("Woof"), handleIfMessage => handleIfMessage.Equals("Bark like a dog"));
}
}
If we were to send this actor the following messages they would be received and handled:
IActorRef someActor = actorSystem.ActorOf<SomeActor>("Some");
someActor.Tell("Tell me a joke");
someActor.Tell("Say Hi");
someActor.Tell("Bark like a dog");
However, the following would not be received as it has no matching predicate (even though the message is still of type string):
someActor.Tell("Say bye");
To learn more about Akka.NET, check out the docs or my Pluralsight courses: Building Concurrent Applications with the Actor Model in Akka.NET and Implementing Logging and Dependency Injection in Akka.NET.
You can start watching with a Pluralsight free trial.
SHARE: