Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@ToJans
Created September 3, 2010 22:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ToJans/564651 to your computer and use it in GitHub Desktop.
Save ToJans/564651 to your computer and use it in GitHub Desktop.
synchronous node.js like thingy for .Net
// node for .net POC using a CQRS messagebus
// tojans@twitter
// you need the source from http://www.corebvba.be/blog/post/Winning-the-game-with-CQRSevent-sourcing-and-BDD.aspx to compile
using System;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using NetNode.Services;
using SimpleCQRS2.Example.Domain.Handlers;
using SimpleCQRS2.Example.Domain.Model;
using SimpleCQRS2.Example.Views;
using SimpleCQRS2.Framework;
using SimpleCQRS2.Framework.Services;
namespace NetNode
{
class AppConverter: HttpListenerRequestConverter
{
ICommandBus cb;
IAnIOC ioc;
IAggregateRootStore arstore;
IEventStore evstore;
public AppConverter()
{
ioc = new IOCStub();
foreach(var t in new Type[] {typeof(PositiveNumberHandler),typeof(SomeReadModelUpdater)})
{
var inst = Activator.CreateInstance(t);
ioc.Register(t,inst);
foreach(var t2 in CQRSCommandBus.GetMessageHandlerInterfaces(t))
ioc.Register(t2,inst);
}
evstore = new EventStore();
arstore = new AggregateRootStore();
cb = new CQRSCommandBus(ioc,evstore,arstore);
Register(req=> true, (req,resp) => GetView(null));
Register(req=> Regex.IsMatch(req.RawUrl,"/create")
, (req,resp) =>
{
cb.HandleCommand(new PositiveNumber.Create() { AggregateRootId = Guid.NewGuid()});
return GetView("positive number created");
});
Register(req=> Regex.IsMatch(req.RawUrl,"/increment/.+")
, (req,resp) =>
{
var guid = Guid.Parse(Regex.Match(req.RawUrl,"/increment/(?<guid>.+)").Groups["guid"].Value);
cb.HandleCommand(new PositiveNumber.Increment() { AggregateRootId = guid});
return GetView("Number incremented");
});
Register(req=> Regex.IsMatch(req.RawUrl ,"/decrement/.+")
, (req,resp) =>
{
var guid = Guid.Parse(Regex.Match(req.RawUrl,"/decrement/(?<guid>.+)").Groups["guid"].Value);
cb.HandleCommand(new PositiveNumber.Decrement() { AggregateRootId = guid});
return GetView("Number decremented");
});
}
private string GetView(string status)
{
var sb = new StringBuilder();
sb.Append("<html><body>");
if (!string.IsNullOrEmpty(status))
{
sb.AppendFormat("<h3>{0}</h3>",status);
}
var rm = ioc.Resolve<SomeReadModelUpdater>().First().Values;
sb.Append("<a href='/create'>Add a postive number</a>");
sb.Append("<ul>");
foreach(var k in rm.Keys)
{
sb.Append("<li>");
sb.Append("<a href='/increment/"+k.ToString() + "'>+</a>");
sb.Append(rm[k]);
sb.Append("<a href='/decrement/"+k.ToString() + "'>-</a>");
sb.Append("</li>");
}
sb.Append("</ul>");
sb.Append("</body></html>");
return sb.ToString();
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
namespace NetNode.Services
{
public class HttpListenerRequestConverter
{
class RequestConverter
{
public Predicate<HttpListenerRequest> IsMatch;
public Func<HttpListenerRequest,HttpListenerResponse,string> Convert;
}
List<RequestConverter> Converters = new List<HttpListenerRequestConverter.RequestConverter>();
public HttpListenerRequestConverter()
{
Register(req => true
,(req,resp) =>
{
resp.StatusCode = (int)HttpStatusCode.BadRequest;
return "Unmapped request";
});
}
public void Register(Predicate<HttpListenerRequest> IsMatch,Func<HttpListenerRequest,HttpListenerResponse,string> Convert)
{
Converters.Insert(0,new RequestConverter() {IsMatch = IsMatch, Convert = Convert });
}
public string GetResponse(HttpListenerRequest request,HttpListenerResponse response)
{
var c = Converters.Where(x=>x.IsMatch(request)).First();
return c.Convert(request,response);
}
}
}
using System;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using NetNode.Services;
using SimpleCQRS2.Example.Domain.Handlers;
using SimpleCQRS2.Example.Domain.Model;
using SimpleCQRS2.Example.Views;
using SimpleCQRS2.Framework;
using SimpleCQRS2.Framework.Services;
namespace NetNode
{
class Program
{
public static void Main(string[] args)
{
Console.WriteLine("Hello World!");
// TODO: Implement Functionality Here
var urlroot = "http://localhost:8080/";
Console.WriteLine("you can surf to "+urlroot);
init(urlroot);
}
static void init(params string[] prefixes)
{
var Converter = new AppConverter();
if (!HttpListener.IsSupported)
{
Console.WriteLine ("Windows XP SP2 or Server 2003 is required to use the HttpListener class.");
return;
}
// URI prefixes are required,
// for example "http://localhost:8080/index/".
if (prefixes == null || prefixes.Length == 0)
throw new ArgumentException("prefixes");
// Create a listener.
HttpListener listener = new HttpListener();
// Add the prefixes.
foreach (string s in prefixes)
{
listener.Prefixes.Add(s);
}
listener.Start();
Console.WriteLine("Listening...");
while (true)
{
// Note: The GetContext method blocks while waiting for a request.
HttpListenerContext context = listener.GetContext();
HttpListenerRequest request = context.Request;
// Obtain a response object.
HttpListenerResponse response = context.Response;
// Construct a response.
string responseString = Converter.GetResponse(request,response);
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(responseString);
// Get a response stream and write the response to it.
response.ContentLength64 = buffer.Length;
System.IO.Stream output = response.OutputStream;
output.Write(buffer,0,buffer.Length);
// You must close the output stream.
output.Close();
}
listener.Stop();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment