在实现通用接口的动态对象上调用方法

时间:2014-11-09 16:54:05

标签: c# dynamic reflection

我有一个查询对象从服务总线进入,从JSON反序列化 - 看起来像是在工作......

public TResult Execute<TResult>(IQuery<TResult> query) where TResult : class {
....
var types = Assembly.GetExecutingAssembly().GetTypes();            
var queryType = types.FirstOrDefault(z => z.Name.Equals(message.MessageType));
var queryObj = JsonConvert.DeserializeObject(message.Json, queryType, settings);

然后我希望将它与已经为其注册的处理程序匹配(找到实现TResult IQueryHandler的方法) - 很好。对TResult的唯一限制是它是一个类。

var handlerType = typeof(IQueryHandler<,>);
var genericType = handlerType.MakeGenericType(new[] { queryType, typeof(TResult) });
var handler = (dynamic)Startup.SimpleInjector.Instance.GetInstance(genericType);

然后我想用我重建的查询对象调用此处理程序上的Handle方法,但这就是我得到的地方:

result = handler.Handle(queryObj);
Log.Instance.Info("result {0}", result);

An exception occurred, MassTransit.Exceptions.RequestException: The response handler threw an exception ---> Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: The best overloaded method match for 'HomeApi.Handlers.Workflow.AnyWorkflowsStartWithEventQueryHandler.Handle(HomeApi.Queries.AnyWorkflowsStartWithEventQuery)' has some invalid arguments

我已经验证了处理程序是从SimpleInjector返回的(虽然将它转换为动态会导致问题吗?)并且处理程序接受查询并返回预期的TResult,所以不确定为什么我&#39 ;得到这个结果。任何帮助表示赞赏。

这里是IQueryHandler&lt;,&gt;

的定义
public interface IQueryHandler<T, out TR> where T : class where TR : class
{
    TR Handle(T query);
}

和IQuery:

public interface IQuery<T> where T : class
{
    string Type { get; }
}

1 个答案:

答案 0 :(得分:1)

假设JsonConvert.DeserializeObject(message.Json, queryType, settings);返回object,您希望实际使用真实类型调用Handle函数,例如:

result = handler.Handle((dynamic)queryObj);

现在,您正在呼叫handler.Handle<MyRealType>(object)