This tutorial provides step by step instructions for creating a basic functioning Orleans application. It is designed to be self-contained and minimalistic, with the following traits.
Keep in mind, this is only a tutorial and lacks appropriate error handling and other goodies that would be useful for a production environment. However, it should help the reader get a real hands-on for all the different facets of Orleans and allow them to focus their continued learning on the parts most relevant to them.
You can find the final source code in Samples\Tutorial.Minimal folder (see latest version online).
For this tutorial we’re going to need to create 3 projects. A Library that contains the interfaces (Communication interfaces), a library that contains the implementation (called Grains), and a simple console application that will Host our Silo. For further understanding of this terminology please see the document Getting Started with Orleans.
The Solution will eventually look like this. (Missing files will be added in sections below)

We use just the default project types in c#.
Orleans is available via Nuget. The primary goodness is in Microsoft.Orleans.Core but we will be including packages that provide additional functionality. Specifically, we will be using Template packages, which provide the autocode generation for us our Grains and Interfaces, and the Runtime which is used for hosting.
In GrainInterfaces create an interface IHello.cs
public interface IHello : Orleans.IGrainWithIntegerKey
{
Task<string> SayHello(string msg);
}
In GrainCollection create a class HelloGrain.cs
class HelloGrain : Orleans.Grain, IHello
{
public Task<string> SayHello(string msg)
{
return Task.FromResult(string.Format("You said {0}, I say: Hello!", msg));
}
}
The host requires the most amount of attention to get Orleans up and running. Throughout future tutorials, much of this will change, or go away (Orleans comes with a nice precanned SiloHost and the Extension provides a template that simplifies this).
However this small implementation should demonstrate the basics of getting started.
Change App.config enable the recommended server style garbage collection
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<runtime>
<gcServer enabled="true"/>
</runtime>
</configuration>
Within the Host project, add an XML file that will be used for cluster configuration called OrleansConfiguration.xml
Make sure it is set to Copy to Output directory:
<?xml version="1.0" encoding="utf-8"?>
<OrleansConfiguration xmlns="urn:orleans">
<Globals>
<SeedNode Address="localhost" Port="11111" />
</Globals>
<Defaults>
<Networking Address="localhost" Port="11111" />
<ProxyingGateway Address="localhost" Port="30000" />
</Defaults>
</OrleansConfiguration>
It is possible to configure this within the code, but it is fairly temperamental.
Program.cs is our most length code block. We are attempting to accomplish a number of objectives
The Orleans samples come with a very nice class called HostWrapper, which abstracts some of the boiler plate within this example. We’re going to do this by hand, but for a more robust implementation, it is worth exploring.
using Orleans.Runtime.Host;
using Orleans;
using System.Net;
class Program
{
static SiloHost siloHost;
static void Main(string[] args)
{
// Orleans should run in its own AppDomain, we set it up like this
AppDomain hostDomain = AppDomain.CreateDomain("OrleansHost", null,
new AppDomainSetup()
{
AppDomainInitializer = InitSilo
});
DoSomeClientWork();
Console.WriteLine("Orleans Silo is running.\nPress Enter to terminate...");
Console.ReadLine();
// We do a clean shutdown in the other AppDomain
hostDomain.DoCallBack(ShutdownSilo);
}
static void DoSomeClientWork()
{
// Orleans comes with a rich XML and programmatic configuration. Here we're just going to set up with basic programmatic config
var config = Orleans.Runtime.Configuration.ClientConfiguration.LocalhostSilo(30000);
GrainClient.Initialize(config);
var friend = GrainClient.GrainFactory.GetGrain<IHello>(0);
var result = friend.SayHello("Goodbye").Result;
Console.WriteLine(result);
}
static void InitSilo(string[] args)
{
siloHost = new SiloHost(System.Net.Dns.GetHostName());
// The Cluster config is quirky and weird to configure in code, so we're going to use a config file
siloHost.ConfigFileName = "OrleansConfiguration.xml";
siloHost.InitializeOrleansSilo();
var startedok = siloHost.StartOrleansSilo();
if (!startedok)
throw new SystemException(String.Format("Failed to start Orleans silo '{0}' as a {1} node", siloHost.Name, siloHost.Type));
}
static void ShutdownSilo()
{
if (siloHost != null)
{
siloHost.Dispose();
GC.SuppressFinalize(siloHost);
siloHost = null;
}
}
}
At this point we should be able to run Host. A console should appear with a large amount of logging text, at the end it should look like this

Within the appropriate bin directory (Debug/Release) there will be a number of log files showing this information as well. The amount and method of logging is configurable.