Skip to content

Instantly share code, notes, and snippets.

@ruslander
Last active August 29, 2015 14:16
Show Gist options
  • Save ruslander/3ec2c1463cabf5b7d1fc to your computer and use it in GitHub Desktop.
Save ruslander/3ec2c1463cabf5b7d1fc to your computer and use it in GitHub Desktop.
Polymorphic dispatch
class Program
{
static void Main(string[] args)
{
var p1 = new ChatServerProcess();
p1.When(new NewMessage(){Text = "Hello"});
p1.When(new NewMessage(){Text = "World"});
var p2= new ChatServerProcess();
p2.HydrateState(p1.HandOffState());
var transportMessage = BinarySerializer.Serialize(new UserJoin() { Name = "Russel" });
p2.Dispatch(transportMessage);
Console.ReadKey();
}
}
public class DistributedProcess<T>
{
public T Data { get; set; }
public void HydrateState(string state)
{
Data = (T)BinarySerializer.Deserialize(state);
}
public string HandOffState()
{
return BinarySerializer.Serialize(Data);
}
public void Dispatch(string transportMessage)
{
var command = BinarySerializer.Deserialize(transportMessage);
((dynamic)this).When((dynamic)command);
}
}
public class BinarySerializer
{
public static string Serialize(object obj)
{
using (var stream = new MemoryStream())
{
var formatter = new BinaryFormatter();
formatter.Serialize(stream, obj);
stream.Flush();
stream.Position = 0;
return Convert.ToBase64String(stream.ToArray());
}
}
public static object Deserialize(string payload)
{
var b = Convert.FromBase64String(payload);
using (var stream = new MemoryStream(b))
{
var formatter = new BinaryFormatter();
stream.Seek(0, SeekOrigin.Begin);
return formatter.Deserialize(stream);
}
}
}
// example
public class ChatServerProcess : DistributedProcess<ChatServerState>
{
public ChatServerProcess()
{
Data = new ChatServerState();
}
public List<string> GetHistory()
{
return Data.RoomMessages;
}
public void When(NewMessage message)
{
Data.RoomMessages.Add(message.Text);
}
public void When(UserJoin message)
{
Data.OnlineUsers.Add(message.Name);
}
public void When(UserLeft message)
{
Data.OnlineUsers.Add(message.Name);
}
}
[Serializable]
public class NewMessage
{
public string Text { get; set; }
}
[Serializable]
public class UserJoin
{
public string Name { get; set; }
}
[Serializable]
public class UserLeft
{
public string Name { get; set; }
}
[Serializable]
public class ChatServerState
{
public List<string> RoomMessages = new List<string>();
public List<string> OnlineUsers = new List<string>();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment