简体   繁体   English

使用反射,调用通用异步方法

[英]Using Reflection, Invoke Generic Async Method

I have a pattern that looks like this when used with known, compile-time types: 与已知的编译时类型一起使用时,我有一个类似于以下的模式:

// given a method like this...
public RSType ComputeSomething(RQType rq) {
    RSType rs = new RSType();
    // do something to rs here, based on rq...
    return rs;
}

// I'm able to do create an event handler like this
eventHandlers.RequestResponseAsync<RQType, RSType>(rq =>
    Task.Factory.StartNew(() =>
    {
        return ComputeSomething(rq);
    }));

And now I'm trying to use reflection so that a function like ComputeSomething can be found at runtime, and then RequestResponseAsync invoked as appropriate. 现在,我正在尝试使用反射,以便可以在运行时找到ComputeSomething之类的函数,然后在适当时调用RequestResponseAsync。

There is a non-async version, and I've got that working. 有一个非异步版本,我已经可以使用了。 For example, given the same ComputeSomething: 例如,给定相同的ComputeSomething:

// get the handler method, and types
var handlerType = Assembly.LoadFrom("SomeAssembly").GetType("SomeNameSpace.SomeClass");
var handlerMethod = handlerType.GetMethod("ComputeSomething");
var handlerParamType = handlerMethod.GetParameters().FirstOrDefault().ParameterType;
var handlerReturnType = handlerMethod.ReturnType;

// get MethodInfo for a generic RequestResponseAsync
var respond = eventHandlers.GetType().GetMethod("RequestResponseAsync");
var genericRespond = respond.MakeGenericMethod(new Type[] { handlerParamType, handlerReturnType });

// create a delegate to pass to the invocation
var delegateType = typeof(Func<,>).MakeGenericType(handlerParamType, handlerReturnType);
var del = Delegate.CreateDelegate(delegateType, handlerMethod);

// invoke the method
genericRespond.Invoke(eventHandlers, new[] { del });

But my brain is too small to figure out how to take it to the next, Async level. 但是我的大脑很小,无法弄清楚如何将其带入下一个异步级别。

Can someone show me? 有人可以告诉我吗?

I'm not sure if someone suggested this a possibility, but I wanted to close the loop. 我不确定是否有人建议这样做,但是我想结束循环。

Here's what I've done, which seems to work. 这是我所做的,似乎可行。

I've created a generic Func factory function which I then call via reflection. 我创建了一个通用的Func工厂函数,然后通过反射对其进行调用。

Func<RQ,Task<RS>> RqRsAsyncHandler<RQ,RS>(Func<RQ,RS> handler) 
{
    return (RQ rq) =>
    {
        return Task.Factory.StartNew(() =>
        {
            return handler(rq);
        });
    };
}

Then, I basically proceed as before but, instead, pass in the Func created by the function factory. 然后,我基本上像以前一样进行操作,但是,传入函数工厂创建的Func。

// get a delegate for the actual handler
var delegateType = typeof(Func<,>).MakeGenericType(handlerParamType, handlerReturnType);
var del = Delegate.CreateDelegate(delegateType, handlerMethod);

// get a Func that wraps that handler in a tracer handler
var RqRsAsyncHandlerMethodInfo = typeof(Container).GetMethod("RqRsAsyncHandler");
var RqRsAsyncHandlerMethodInfoGeneric = RqRsAsyncHandlerMethodInfo.MakeGenericMethod(handlerParamType, handlerReturnType);
var wrapperFunc = RqRsAsyncHandlereMethodInfoGeneric.Invoke(null, new object[] { del });

// get the eventHandlers method
MethodInfo respondMethod = typeof(EventHandlers).GetMethod("RespondAsync");
MethodInfo genericRespondMethod = respondMethod.MakeGenericMethod(new[] { handlerParamType, handlerReturnType });

// invoke the Bus method
genericRespondMethod.Invoke(eventHandlers , new[] { wrapperFunc });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM