I want to implement a CommandBus
that can Dispatch
some Commands
to CommandHandlers
.
- A
Command
is a simple a DTO describing what should happen. For instance : "Increment counter by 5" - A
CommandHandler
is able to handle a precise type ofCommand
. - The
CommandBus
takes aCommand
and executes theCommandHandler
that is able to handle it.
The code I wrote does not compile.
Compiler complains cannot convert from 'IncrementHandler' to 'Handler<Command>'
.
I don't understand why, because IncrementHandler
implements Handler<Increment>
and Increment
implements Command
I've tried both in
and out
modifiers on the generic interfaces, it doesn't solve the problem.
Is there a way to achieve this with only interfaces ?
[TestClass]
public class CommandBusTest
{
[TestMethod]
public void DispatchesProperly()
{
var handler = new IncrementHandler(counter: 0);
var bus = new CommandBus(handler); // <--Doesn't compile: cannot convert from 'IncrementHandler' to 'Handler<Command>'
bus.Dispatch(new Increment(5));
Assert.AreEqual(5, handler.Counter);
}
}
public class CommandBus
{
private readonly Dictionary<Type, Handler<Command>> handlers;
public CommandBus(params Handler<Command>[] handlers)
{
this.handlers = handlers.ToDictionary(
h => h.HandledCommand,
h => h);
}
public void Dispatch(Command commande) { /*...*/ }
}
public interface Command { }
public interface Handler<TCommand> where TCommand : Command
{
Type HandledCommand { get; }
void Handle(TCommand command);
}
public class Increment : Command
{
public Increment(int value) { Value = value; }
public int Value { get; }
}
public class IncrementHandler : Handler<Increment>
{
// Handler<Increment>
public Type HandledCommand => typeof(Increment);
public void Handle(Increment command)
{
Counter += command.Value;
}
// Handler<Increment>
public int Counter { get; private set; }
public IncrementHandler(int counter)
{
Counter = counter;
}
}