如何将运行时解析的IHandler<T>对象转为可await类型?
运行时解析泛型IHandler后调用HandleAsync的解决方案
针对你遇到的问题,这里提供三种实用的解决办法:
方案一:反射调用方法
直接通过反射获取HandleAsync方法并执行,无需修改原有接口:
var myObject = new MyObject(); var handlerType = typeof(IHandler<>).MakeGenericType(myObject.GetType()); var handler = _serviceProvider.GetService(handlerType); if (handler != null) { // 获取HandleAsync方法 var handleMethod = handlerType.GetMethod(nameof(IHandler<object>.HandleAsync)); // 调用方法得到Task实例 var task = (Task)handleMethod.Invoke(handler, null); await task; // 如果需要获取返回的T实例,可通过反射取Result属性 var resultProp = task.GetType().GetProperty(nameof(Task<object>.Result)); var result = resultProp.GetValue(task); // result即为T类型的实例 }
优点:无需改动原有代码结构;缺点:反射性能略低,代码可读性一般。
方案二:新增非泛型基接口
给泛型接口加一个非泛型基接口,让具体实现类同时实现两个接口,这样解析后可直接转为非泛型接口调用:
首先修改接口定义:
// 新增非泛型基接口 public interface IHandler { Task HandleAsync(); object GetResult(); } // 泛型接口继承非泛型接口 public interface IHandler<T> : IHandler { new Task<T> HandleAsync(); }
然后实现具体处理器时,补充非泛型接口的实现:
public class MyObjectHandler : IHandler<MyObject> { private MyObject _result; public async Task<MyObject> HandleAsync() { // 业务逻辑示例 _result = new MyObject(); return _result; } // 显式实现非泛型接口的HandleAsync async Task IHandler.HandleAsync() { await HandleAsync(); } public object GetResult() { return _result; } }
最后解析调用:
var myObject = new MyObject(); var handlerType = typeof(IHandler<>).MakeGenericType(myObject.GetType()); var handler = _serviceProvider.GetService(handlerType) as IHandler; if (handler != null) { await handler.HandleAsync(); var result = handler.GetResult(); // result即为T类型的实例 }
优点:类型安全,性能好;缺点:需要修改原有接口定义,侵入性较强。
方案三:使用dynamic类型
利用C#的dynamic特性,跳过编译时类型检查,直接调用方法:
var myObject = new MyObject(); var handlerType = typeof(IHandler<>).MakeGenericType(myObject.GetType()); dynamic handler = _serviceProvider.GetService(handlerType); if (handler != null) { // 直接await,运行时自动解析方法 var result = await handler.HandleAsync(); // result在运行时为T类型,编译时是dynamic }
优点:代码最简洁,无需修改原有代码;缺点:编译时无类型校验,若handler类型错误或方法名拼写错误,会在运行时抛出异常。
内容的提问来源于stack exchange,提问作者Reyhn
相关产品推荐
相关产品推荐

