0

I'm building a command dispatch function, such that given an object deriving from a base class, it resolves (from an IoC container) a handler for the command type and sends the command object there for processing. My types look like this:

public abstract class CommandBase { }
public interface ICommandHandler<in TCommand> where TCommand : CommandBase { 
    void Process(TCommand command);
}

Sample implementation:

public class TestCommand : CommandBase {
    // Some parameters
}
public class TestHandler : ICommandHandler<TestCommand> {
    public void Process(TestCommand command) {
        // Do something
    }
}

When I recieve a call, I can (almost) retrieve a matching handler from my container like this:

public ICommandHandler<T> GetHandler<T>(T command) where T : CommandBase
{
    var handlerInterface = typeof (ICommandHandler<>);
    var handlerType = handlerInterface.MakeGenericType(command.GetType());
    var handler = _scope.Resolve(handlerType) as ICommandHandler<T>;
    // Some magic?
    return handler; 
}

Which I want to call like this:

public void HandleCommand(CommandBase command) {
    var handler = GetHandler(command);
    handler.Process(command);
}

Problem is that the type parameter T is CommandBase, so the cast will be to ICommandHandler<CommandBase>, which isn't implemented by TestHandler, for instance. And no matter if I can cast it properly, I cannot return an implementation of ICommandHandler<TestCommand> when the T=CommandBase.

Is there some way around this? I'm not specifically locked in the GetHandler-method, anything that fits into the HandleCommand method is fine (I need to have a single entry point which accepts a base class, and I cannot do some switch/case monolith)

carlpett
  • 12,203
  • 5
  • 48
  • 82
  • A good substitute for a switch/case monolith is to maintain a dictionary that relates the Command with the handlers. Then you just probe into the dictionary instead of hard-coding it with a switch. – Keith Payne Feb 27 '14 at 14:52
  • @KeithPayne: Hm, not sure I see how - what type would I pull out of the dictionary? – carlpett Feb 27 '14 at 15:25
  • What is the problem with what you've posted? The only thing that jumps out is that you could write `public void HandleCommand(T command) where T : CommandBase ...`. But that depends. What is the problem that you are trying to solve? – Keith Payne Feb 27 '14 at 22:34
  • @KeithPayne: The problem is that `T` will be `CommandBase`, not `TestCommand`, so I cannot cast `TestHandler` to `ICommandHandler`, since `TestHandler` does not implement `ICommandHandler`, but rather `ICommandHandler`. – carlpett Feb 28 '14 at 08:59

0 Answers0