using System.Collections.Generic;
public interface IRepository
void Add(Dictionary<string, string> data);
public sealed class FakeUserRepository : IRepository
private readonly List<Dictionary<string, string>> _repo = new List<Dictionary<string, string>>();
public void Add(Dictionary<string, string> data)
Console.WriteLine($"User {data["name"]} {data["surname"]} added into the repository");
public List<Dictionary<string,string>> Data => _repo;
IEnumerable<ICommand> Consume();
public sealed class FakeUserQueue : IQueue
private readonly List<ICommand> _queue = new List<ICommand>();
public void Push(ICommand command)
public IEnumerable<ICommand> Consume()
foreach (ICommand command in _queue)
public interface ICommandBus
ICommandBus Route(string command);
void To(ICommandHandler handler);
public sealed class FakeCommandBus : ICommandBus
private string _tmpCommand = "";
private readonly Dictionary<string, ICommandHandler> _routes = new Dictionary<string, ICommandHandler>();
private readonly IQueue _queue;
public FakeCommandBus(IQueue queue)
public ICommandBus Route(string command)
public void To(ICommandHandler handler)
if (string.IsNullOrEmpty(_tmpCommand))
throw new ArgumentException("In order to use 'To' method, first you have to define a command with 'Route' method.");
_routes.Add(_tmpCommand, handler);
foreach (var item in _queue.Consume())
var command = _routes[item.GetType().Name];
var method = command.GetType().GetMethod("Handle");
method.Invoke(command, new object[] { item });
public interface ICommand {}
public abstract class Command : ICommand
protected Command(Dictionary<string, string> payload)
protected Dictionary<string, string> Payload { get; }
public sealed class RegisterUser : Command
public RegisterUser(string name, string surname)
: base(new Dictionary<string, string>{{"name", name}, {"surname", surname}})
public string Name => base.Payload["name"];
public string Surname => base.Payload["surname"];
public interface ICommandHandler {}
public abstract class CommandHandlerBase<T> : ICommandHandler
protected CommandHandlerBase(IRepository repository)
protected IRepository Repository { get; }
public abstract void Handle(T command);
public sealed class RegisterUserHandlerBase : CommandHandlerBase<RegisterUser>
public RegisterUserHandlerBase(IRepository repository) : base(repository) {}
public override void Handle(RegisterUser command)
Console.WriteLine(command.GetType().Name + " Executed.");
base.Repository.Add(new Dictionary<string, string>
{"name", command.Name}, {"surname", command.Surname}
static void Main(string[] args)
var user1 = new RegisterUser(
var user2 = new RegisterUser(
var fakeUserQueue = new FakeUserQueue();
var fakeUserRepo = new FakeUserRepository();
var fakeCommandBus = new FakeCommandBus(fakeUserQueue);
.To(new RegisterUserHandlerBase(fakeUserRepo))
fakeUserQueue.Push(user1);
fakeUserQueue.Push(user2);
Console.WriteLine("Users in Repository:");
for (int i = 0; i < fakeUserRepo.Data.Count; i++)
Console.WriteLine($"{i + 1} - {fakeUserRepo.Data[i]["name"]} {fakeUserRepo.Data[i]["surname"]}");