Dynamic keyword does not work with IoC but classic reflection does
c#, dynamic, reflection
Solution
You need to change your code to look like this:
public void Invoke(Contracts.Commands.Command command)
{
var handlerType = types[command.GetType()];
dynamic handler = kernel.Get(handlerType);
dynamic cmd = command;
handler.Execute(cmd);
}
Notice that the `command` parameter is first assigned to a dynamic local variable (`cmd`). This allows the type of `cmd` to be evaluated at runtime and keeps the call to `Execute` truly dynamic; where as NOT doing it this way, the `Execute` method is assumed to have a fixed signature of `Execute(Contracts.Commands.Command command)`
Problem
I have made a little CQRS API for our system I tried to replace some reflection code by using the dynamic keyword but it does not work Each command handler is Generic `CommandHandler<TCommand>` with a Method `void Execute(TCommand Command)` With reflection it works ``` public void Invoke(Contracts.Commands.Command command) { var handlerType = types[command.GetType()]; var handler = kernel.Get(handlerType); var method = handlerType.GetMethod("Execute"); method.Invoke(handler, new object[] { command }); } ``` `Kernel.Get` is the untyped version of `kernel.Get<T>` in our IoC (Ninject). This works and the generic method Execute of T fires This code fails with a argument mismatch exception ``` public void Invoke(Contracts.Commands.Command command) { var handlerType = types[command.GetType()]; dynamic handler = kernel.Get(handlerType); handler.Execute(command); } ``` If i statically declare the type it works with dynamic ``` dynamic handler = new TestCommandHandler(); handler.Execute(new TestCommand()); ``` edit: Some more info to answer questions in comments - handlerType is a concrete class that implements the abstract class `CommandHandler<TCommand> where TCommand : Command` - The execute method is declared in the abstract class as `public virtual void Execute(TCommand command)` - TestCommand implements the abstract Class Command Strange thing is that the same Handler and command works if I statically declare them strongly typed, last example (In the real world example I have dependencies in the constructor though edit2 Stacktrace at CallSite.Target(Closure , CallSite , Object , Command ) at System.Dynamic.UpdateDelegates.UpdateAndExecuteVoid2[T0,T1](CallSite site, T0 arg0, T1 arg1) at XXX.Business.Command.CommandHandlerInvoker.Invoke(Command command) in C:\XXX.Business\Command\CommandHandlerInvoker.cs:line 29 at XXX.Web.XXXService.Execute(Command command) in C:\XXX.Web\ExfiService.svc.cs:line 29 at XXX.Web.Controllers.ComplianceController.XXX(XXXViewModel viewModel) in C:\XXX.Web\Controllers\XXXController.cs:line 52 at lambda_method(Closure , ControllerBase , Object[] ) at System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters) at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters) at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters) at System.Web.Mvc.ControllerActionInvoker.<>c_DisplayClass15.b_12() at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation) - Exception The best overloaded method match for `XXX.Business.Command.CommandHandler<XXX.Contracts.Commands.TestCommand>.Execute(XXX.Contracts.Commands.TestCommand)' has some invalid arguments` Error message is stating the abstract class of T not the concrete class, but handlerType in above code is the concrete class