Autofac中运行时已知泛型参数T时如何动态调用ISyncedDataService<T>的GetItems方法
动态调用泛型服务实现方案
核心调用逻辑
假设你在运行时已经获取到了泛型参数T对应的Type实例(记为runtimeT,比如通过类型扫描、配置映射得到的typeof(T1)、typeof(T2)等),可以按照以下步骤实现动态调用,无需硬编码if-else分支:
// 1. 构造封闭泛型接口类型 ISyncedDataService<runtimeT> Type closedServiceType = typeof(ISyncedDataService<>).MakeGenericType(runtimeT); using var scope = App.Container.BeginLifetimeScope(); // 2. 从Autofac容器解析对应服务实例 object service = scope.Resolve(closedServiceType); // 3. 获取接口定义的GetItems方法元数据 MethodInfo getItemsMethod = closedServiceType.GetMethod(nameof(ISyncedDataService<BaseDBModel>.GetItems))!; // 4. 调用方法,用dynamic处理异步Task的等待,避免线程阻塞 dynamic resultTask = getItemsMethod.Invoke(service, parameters: null)!; List<BaseDBModel> items = await resultTask;
如果需要调用带参数的方法,只需要把参数按顺序放到Invoke的第二个参数数组里即可。
泛型扩展方法的MethodInfo获取方案
扩展方法本质是定义在静态类中的静态方法,不属于扩展的目标类型本身,因此无法直接通过服务类型的GetMethod方法获取,需要到扩展方法的定义类中搜索,示例如下:
假设你的扩展方法定义在SyncedDataServiceExtensions静态类中:
public static class SyncedDataServiceExtensions { // 示例泛型扩展方法 public static Task<int> BatchDelete<T>(this ISyncedDataService<T> service, List<T> items) where T : BaseDBModel { // 省略实现逻辑 } }
获取该泛型扩展方法的代码如下:
// 1. 拿到扩展方法所在静态类的Type Type extClassType = typeof(SyncedDataServiceExtensions); // 2. 搜索匹配的泛型方法定义 MethodInfo genericMethodDef = extClassType.GetMethods(BindingFlags.Public | BindingFlags.Static) .First(m => { // 匹配方法名、泛型参数数量、参数数量 if (m.Name != nameof(SyncedDataServiceExtensions.BatchDelete) || !m.IsGenericMethodDefinition || m.GetParameters().Length != 2) return false; return true; }); // 3. 填充运行时泛型参数,得到可执行的封闭方法元数据 MethodInfo closedMethod = genericMethodDef.MakeGenericMethod(runtimeT); // 4. 调用扩展方法:第一个参数为服务实例,后续参数为方法入参 var paramList = new List<BaseDBModel> { /* 省略参数构造逻辑 */ }; dynamic resultTask = closedMethod.Invoke(null, new object[] { service, paramList })!; int deleteCount = await resultTask;
内容的提问来源于stack exchange,提问作者Abhijith C R
相关产品推荐
相关产品推荐

