Динамически вызывать метод для общей цели

У меня общий интерфейсICommandHandler<> который будет иметь несколько реализаций, каждая для обработки конкретной реализацииICommandНапример:

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

Когда мне даютICommand объект, который я пытаюсь отправить его динамически к правильномуICommandHandler, На данный момент я использовал довольно простой подход отражения сInvoke в моем классе диспетчера:

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 });
}

Есть 2 проблемы с этим подходом. Во-первых, он использует медленное отражение. Во-вторых, если метод выдает какое-либо исключение, он будет помещен вTargetInvocationException и я потеряю трассировку стека, если перезапущу ее.

Я разработал способ сделать вызов, создав делегата и используяDynamicInvoke но это не решает проблему с исключениями (и я не уверен,DynamicInvoke действительно лучше, чемInvoke):

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);
}

У меня вопрос, есть ли лучший способ добиться того, что я пытаюсь сделать? Желательно, чтобы я мог сделать строго типизированный звонок вместо полученияobject и глядя вверхMethodInfo, Я предполагаю, что это невозможно, потому что тип не известен во время компиляции.

Если это невозможно, то следующим решением будет эффективное решение, которое будет генерировать исключение «изначально».

редактировать: Обновлены примеры кода, чтобы уточнить, что я использую IoC (Ninject) для созданияICommandHandler во время выполнения, а неActivator.CreateInstance() как я впервые поставил. Включен пример того, как это будет использоваться по запросу:

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'

Редактировать 2: Как предлагается ниже, я не могу разыграть результатIoC.Get(handlerType) вICommandHandler<T> потому что я получаюInvalidCastException во время выполнения. Это потому, что во время выполненияT на самом делеICommandЯ предполагаю, потому что командные классы прибывают через WCF и каким-то образом теряют свою строгую типизацию. Код, который вызывает диспетчер, выглядит примерно так:

[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);
    }
}

Ответы на вопрос(2)

Ваш ответ на вопрос