-
-
Save Zshazz/b226372196aee8f1f7be to your computer and use it in GitHub Desktop.
CQRS (without the Qs) as an example of the component pattern
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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