C# Dynamic关键字不适用于IoC,但classic reflection适用
我为我们的系统制作了一个小小的CQRS API 我试图用dynamic关键字替换一些反射代码,但它不起作用 每个命令处理程序都是通用的C# Dynamic关键字不适用于IoC,但classic reflection适用,c#,dynamic,reflection,C#,Dynamic,Reflection,我为我们的系统制作了一个小小的CQRS API 我试图用dynamic关键字替换一些反射代码,但它不起作用 每个命令处理程序都是通用的CommandHandler,带有一个方法void Execute(TCommand命令) 通过反射,它可以工作 public void Invoke(Contracts.Commands.Command command) { var handlerType = types[command.GetType()]; var handler = ke
CommandHandler
,带有一个方法void Execute(TCommand命令)
通过反射,它可以工作
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
是IoC(Ninject)中Kernel.Get
的非类型化版本。这项工作和一般方法执行的T火灾
此代码因参数不匹配异常而失败
public void Invoke(Contracts.Commands.Command command)
{
var handlerType = types[command.GetType()];
dynamic handler = kernel.Get(handlerType);
handler.Execute(command);
}
如果我静态声明它与dynamic一起工作的类型
dynamic handler = new TestCommandHandler();
handler.Execute(new TestCommand());
编辑:更多信息以回答评论中的问题
- handlerType是一个具体的类,它实现了抽象类CommandHandler,其中TCommand:Command
- execute方法在抽象类中声明为
publicvirtualvoidexecute(TCommand命令)
- TestCommand实现抽象类命令
- 奇怪的是,如果我静态地声明它们是强类型的,那么同一个处理程序和命令也可以工作,最后一个例子(在现实世界的例子中,我在构造函数中有依赖项) edit2
- 堆栈跟踪
2个参数)位于
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext
controllerContext,ActionDescriptor ActionDescriptor,IDictionary
2
参数)在
System.Web.Mvc.ControllerActionInvoker.c_DisplayClass15.b_12()
在
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter
筛选器,ActionExecutingContext预文本,函数'1(续)
- 例外情况
XXX.Business.Command.CommandHandler.Execute(XXX.Contracts.Commands.TestCommand)”具有一些无效参数
错误消息指出T的抽象类不是具体类,但上面代码中的handlerType是具体类您需要将代码更改为如下所示:
public void Invoke(Contracts.Commands.Command command)
{
var handlerType = types[command.GetType()];
dynamic handler = kernel.Get(handlerType);
dynamic cmd = command;
handler.Execute(cmd);
}
请注意,
命令
参数首先分配给一个动态局部变量(cmd
)。这允许在运行时评估cmd
的类型,并使对Execute
的调用保持真正的动态;如果不这样做,则假定Execute
方法具有固定签名Execute(Contracts.Commands.Command)
请提供异常的完整堆栈跟踪。handlerType
是一个接口?一个具体类?一个抽象类?并且Execute
public?internal?protected?一个显式接口实现?或者…?同样地,命令
和TestCommand
是dynamic
围绕a:accessibility和b:interfaces vs public Api展开。以下是无法重现您的问题的示例代码:。我将检查绑定是否正确,Execute
是否具有您认为它具有的参数。我可以重现此错误,但只有在CommandHandler.Execut(T)时才能重现此错误
获取一个不是类型T
的参数-在您的例子中,如果处理程序的泛型类型与命令的类型不同,只需快速调试-也许您可以尝试查看命令.GetType().Name
和处理程序.GetType().Name
?确保handler
的类型为TestCommandHandler
,而不是CommandHandler
(虽然,它应该可以工作……我仍然无法复制它)哈哈,我觉得自己像个白痴,我没有想过要尝试它!:P谢谢!