Chamar dinamicamente um método em um destino genérico

Eu tenho uma interface genéricaICommandHandler<> que terá um número de implementações cada para processar uma implementação específica deICommand, por exemplo.:

public class CreateUserCommand : ICommand { ... }
public class CreateUserCommandHandler : ICommandHandler<CreateUserCommand> { ... }

Quando eu sou dado umICommand objeto estou tentando enviá-lo dinamicamente para o corretoICommandHandler. No momento eu usei uma abordagem de reflexão bastante direta com umInvoke na minha classe dispatcher:

public void Dispatch<T>(T command) where T : ICommand
{
    Type commandType = command.GetType();
    Type handlerType = typeof(ICommandHandler<>).MakeGenericType(commandType);
    object handler = IoC.Get(handlerType);
    MethodInfo method = handlerType.GetMethod("Handle");

    method.Invoke(handler, new object[] { command });
}

Existem 2 problemas com essa abordagem. Em primeiro lugar, usa reflexão lenta. Em segundo lugar, se o método lançar algum tipo de exceção, então ele será envolvido em umTargetInvocationException e eu vou perder o rastreio da pilha se eu voltar a jogá-lo.

Eu trabalhei uma maneira de fazer a chamada, criando um delegado e usandoDynamicInvoke mas isso não resolve o problema com exceções (e eu não tenho certezaDynamicInvoke é realmente melhor do queInvoke):

public void Dispatch<T>(T command) where T : ICommand
{
    Type commandType = command.GetType();
    Type handlerType = typeof(ICommandHandler<>).MakeGenericType(commandType);
    object handler = IoC.Get(handlerType);
    MethodInfo method = handlerType.GetMethod("Handle");

    Type actionType = typeof(Action<>).MakeGenericType(commandType);
    Delegate action = Delegate.CreateDelegate(actionType, handler, method);
    action.DynamicInvoke(command);
}

Minha pergunta é, existe uma maneira melhor de conseguir o que estou tentando fazer? De preferência, eu poderia fazer uma chamada fortemente tipificada em vez deobject e olhando para cimaMethodInfo. Eu suponho que isso não é possível, porque o tipo não é conhecido em tempo de compilação.

Se isso não for possível, uma solução eficiente que jogaria a exceção mais 'nativamente' seria a próxima melhor opção.

Editar: Exemplos de código atualizados para esclarecer que estou usando o IoC (Ninject) para criar oICommandHandler em tempo de execução, nãoActivator.CreateInstance() como eu coloquei primeiro. Incluído um exemplo de como isso seria usado conforme solicitado:

var command = new CreateUserCommand() { Name = "Adam Rodger" };
var dispatcher = new CommandDispatcher();
dispatcher.Dispatch(command);
// this would send the message to CreateUserCommandHandler.Handle(command) 
// dynamically and any exceptions would come back 'natively'

Editar 2: Como sugerido abaixo, não posso lançar o resultado deIoC.Get(handlerType) paraICommandHandler<T> porque eu tenho umInvalidCastException em tempo de execução. Isso ocorre porque em tempo de execuçãoT é na verdadeICommand, Eu assumo porque as classes de comando estão chegando ao WCF e de alguma forma conseguem perder sua forte digitação. O código que chama o despachante é parecido com:

[ServiceContract]
public class CommandService
{
    [OperationContract]
    public void Execute(ICommand command) // no type information
    {
        var dispatcher = new CommandDispatcher(); // injected by IoC in real version
        dispatcher.Dispatch(command);
    }
}

questionAnswers(2)

yourAnswerToTheQuestion