This tutorial is intended to give an introduction to using Orleankka by creating a simple greeter actor using C#.

Set up your project

Start Visual Studio and create a new C# Console Application and reference the following packages:

PM> Install-Package Orleankka.RuntimePM> Install-Package Microsoft.Orleans.Server

This will install all client and server-side packages required for demo app.

Create your first actor

First, we need to create a message type that our actor will respond to:

namespace ConsoleApplication11{    // Create a message types that your actor will respond to    // and mark them with [Serializable] attribute. This is smilar to    // object-oriented interface signatures (eg Greet(string who)) but with classes    [Serializable]    public class Greet    {        public string Who { get; set; }    }    [Serializable]    public class Sleep    {}}

Once we have the message type, we can create our actor:

using System;using Orleankka;namespace ConsoleApplication11{    // Create custom actor interface and implement IActorGrain    public interface IGreeter : IActorGrain {}    // Create actor class by inheriting from ActorGrain and implementing custom actor interface    public class Greeter : ActorGrain, IGreeter    {        // Implement receive function (use pattern matching or any other message matching approach)        public override Task<object> Receive(object message)        {            switch (message)            {                case Greet greet:                    return Result("Hello, {msg.Who}!");                case Sleep _:                    Console.WriteLine("Sleeeeping ...");                    return TaskResult.Done;                    break;                default:                    return Unhandled;            }        }    }}

Now it's time to consume our actor. We need to configure Orleans and then register Orleankka. We'll be using simple localhost configuration suitable for demos.

using System;using Orleankka;using Orleankka.Playground;namespace ConsoleApplication11{    [Serializable]    public class Greet    {        public string Who { get; set; }    }    [Serializable]    public class Sleep    {}    public class Greeter : ActorGrain, IGreeter    {        public override Task<object> Receive(object message)        {            switch (message)            {                case Greet greet:                    return Result("Hello, {msg.Who}!");                case Sleep _:                    Console.WriteLine("Sleeeeping ...");                    return TaskResult.Done;                default:                    return Unhandled;            }        }    }    class Program    {        const string DemoClusterId = "localhost-demo";        const string DemoServiceId = "localhost-demo-service";        const int LocalhostSiloPort = 11111;        const int LocalhostGatewayPort = 30000;        static readonly IPAddress LocalhostSiloAddress = IPAddress.Loopback;        static void Main(string[] args)        {            var host = await new SiloHostBuilder()                .Configure(options => {                    options.ClusterId = DemoClusterId;                    options.ServiceId = DemoServiceId;                })                .UseDevelopmentClustering(options => options.PrimarySiloEndpoint = new IPEndPoint(LocalhostSiloAddress, LocalhostSiloPort))                .ConfigureEndpoints(LocalhostSiloAddress, LocalhostSiloPort, LocalhostGatewayPort)                .ConfigureApplicationParts(x => x                    .AddApplicationPart(Assembly.GetExecutingAssembly())                    .WithCodeGeneration())                .UseOrleankka()  // register Orleankka extension                .Build();            // start Orleans server (silo)            await host.StartAsync();            var client = new ClientBuilder()                .ConfigureCluster(options => {                    options.ClusterId = DemoClusterId;                    options.ServiceId = DemoServiceId                })                .UseStaticClustering(options => options.Gateways.Add(new IPEndPoint(LocalhostSiloAddress, LocalhostGatewayPort).ToGatewayUri()))                .ConfigureApplicationParts(x => x                    .AddApplicationPart(Assembly.GetExecutingAssembly())                    .WithCodeGeneration())                .UseOrleankka()                .Build();            // start (connect) Orleans client            await client.Connect();            // get reference to ActorSystem            var system = client.ActorSystem();            // get proxy reference for IGreeter actor            var greeter = system.ActorOf<IGreeter>("id");            // send query to actor (ie Ask)            Console.WriteLine(await greeter.Ask<string>(new Greet {Who = "world"}));            // send command to actor (ie Tell)            await greeter.Tell(new Sleep());            Console.Write("\n\nPress any key to terminate ...");            Console.ReadKey(true);        }    }}

That is it. See more examples in a Samples directory.