Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@Zshazz
Last active August 29, 2015 14:22
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 Zshazz/b226372196aee8f1f7be to your computer and use it in GitHub Desktop.
Save Zshazz/b226372196aee8f1f7be to your computer and use it in GitHub Desktop.
CQRS (without the Qs) as an example of the component pattern
// using DryIoc; // v2.0-RC
void Main()
{
var container = new Container();
container.Register<IObject, ConcreteObject>();
container.Register<IComponent<RunMessage>, RunComponent>(new SingletonReuse());
container.Register<IComponent<ReceiveMessage>, ReceiveComponent>(new SingletonReuse());
container.RegisterInstance(Console.Out, new SingletonReuse());
container.RegisterDelegate<ConcreteObject.ComponentsThatCanHandleMessagesOf>(resolver => ((Type svc) => resolver.ResolveMany(svc, null, null, null, null)));
var myObject = container.Resolve<IObject>();
myObject.Send(new RunMessage()); // "hello world!"
myObject.Send(new RunMessage()); // "error!"
}
public class RunMessage : IMessage {}
public class ReceiveMessage : IMessage
{
public ReceiveMessage(string message) { Message = message; }
public string Message { get; set; }
}
public class RunComponent : IComponent<RunMessage>
{
private IObject _object;
private bool _running = false;
public RunComponent(IObject @object) { _object = @object; }
public void Handle(RunMessage message)
{
if (!_running)
{
_running = true;
_object.Send(new ReceiveMessage("hello world!"));
}
else
_object.Send(new ReceiveMessage("error!"));
}
}
public class ReceiveComponent : IComponent<ReceiveMessage>
{
private TextWriter _writer;
public ReceiveComponent(TextWriter writer) { _writer = writer; }
public void Handle(ReceiveMessage message)
{
_writer.WriteLine(message.Message);
}
}
//Implementation:
// Just a marker interface
public interface IMessage
{}
public interface IComponent<in TMessage>
where TMessage : IMessage
{
void Handle(TMessage message);
}
public interface IObject
{
void Send<TMessage>(TMessage message)
where TMessage : IMessage;
}
public class ConcreteObject : IObject
{
public delegate IEnumerable<object> ComponentsThatCanHandleMessagesOf(Type type);
private ComponentsThatCanHandleMessagesOf _componentsThatCanHandleMessagesOf;
public ConcreteObject(ComponentsThatCanHandleMessagesOf componentsThatCanHandleMessagesOf)
{
_componentsThatCanHandleMessagesOf = componentsThatCanHandleMessagesOf;
}
public void Send<TMessage>(TMessage message)
where TMessage : IMessage
{
var messageType = typeof(IComponent<>).MakeGenericType(message.GetType());
var components = _componentsThatCanHandleMessagesOf(messageType).OfType<IComponent<TMessage>>();
foreach(var component in components)
component.Handle(message);
}
}
@Zshazz
Copy link
Author

Zshazz commented May 28, 2015

Also just to note, this is written in Linqpad 4 in C# Program mode, so that will explain why it doesn't copy-paste directly into Visual Studio

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment