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

本文关键字:异步方法 调用 反射 | 更新日期: 2023-09-27 18:22:15

当与已知的编译时类型一起使用时,我有一个模式看起来像这样:

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

现在我正在尝试使用反射,以便在运行时可以找到像ComputeSomething这样的函数,然后根据需要调用RequestResponseAsync。

有一个非异步版本,我已经开始工作了。例如,给定相同的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 });

但我的大脑太小了,不知道如何将其提升到下一个异步级别。

有人能给我看看吗?

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

我不确定是否有人提出了这种可能性,但我想结束这个循环。

这是我所做的,似乎奏效了。

我创建了一个通用的Func工厂函数,然后通过反射调用它。

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

然后,我基本上像以前一样进行,但相反,传入函数工厂创建的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 });