将对象转换为 Task<T> 并从类型为 Type 的变量设置 T

Dav*_*oss 5 c# asp.net generics reflection asp.net-core

解释起来有点困难,对此我表示歉意。但我需要帮助。我正在研究事件的通用方法。我的所有代码都基于eShopOnContainers 示例,但我的处理程序应该返回一个值。

在 eShopOnContainers 中,只是Task作为返回类型,因此它们可以轻松

var eventType = _subsManager.GetEventTypeByName(eventName);
var integrationEvent = JsonConvert.DeserializeObject(message, eventType);
var concreteType = typeof(IIntegrationEventHandler<>).MakeGenericType(eventType);
await (Task)concreteType.GetMethod("Handle").Invoke(handler, new object[] { integrationEvent });
Run Code Online (Sandbox Code Playgroud)

假设我有

public interface IRequestMessageHandler<in TRequest, TReply>
    {
        Task<TReply> Handle(TRequest request);
    }
Run Code Online (Sandbox Code Playgroud)

就我而言,我需要投射到Task<T>. T存储在变量中的类型

Type concreteHandlerType = typeof(IRequestMessageHandler<,>).MakeGenericType(subscription.RequestType, subscription.ReplyType);
Type concreteReplyType = typeof(Task<>).MakeGenericType(subscription.ReplyType);
Run Code Online (Sandbox Code Playgroud)

然后我需要将结果投射到concreteReplyType

var reply = await (concreteReplyType)concreteType.GetMethod("Handle")?.Invoke(handler, new[] { integrationEvent });
Run Code Online (Sandbox Code Playgroud)

请帮助我,因为我不明白这怎么可能。先感谢您。请让我知道我应该添加哪些信息来帮助您更好地理解。

摆弄代码来重现https://dotnetfiddle.net/X3m4A1

xan*_*tos 4

要解决您的问题,一个简单的解决方案是使用dynamic(请参阅此处)。

var method = concreteType.GetMethod("Handle");
var task = (Task)method.Invoke(handler, new object[] { integrationEvent });

await task;

object result = ((dynamic)task).Result;
Run Code Online (Sandbox Code Playgroud)