如何通过字符串生成的类型实例化泛型仓储?
泛型仓储实例化与方法调用解决方案
核心思路
要通过动态类型实例化泛型仓储并调用方法,需分两步:构造泛型仓储类型并实例化、通过反射调用目标方法。
步骤1:正确实例化泛型仓储
假设你的仓储实现类实现了IEntityBaseRepository<T>接口,按以下逻辑构造并实例化:
public T Create(T dtoEntity) { string entityClassName = dtoEntity.GetType().Name; string repositoryClassName = entityClassName + "Repository"; string repositoryFullName = $"{repositoryNamespace}{repositoryClassName}"; try { // 1. 动态获取实体类型(从指定程序集+命名空间) string entityFullName = $"{entitiesNamespace}{entityClassName}"; Type entityType = assembly.GetType(entityFullName)!; // 2. 构造泛型仓储接口的类型 Type genericRepoInterface = typeof(IEntityBaseRepository<>).MakeGenericType(entityType); // 3. 实例化仓储对象:如果仓储构造函数依赖DbContext等参数,需传入对应实例 object dbContext = // 你的DbContext实例获取逻辑(比如从DI容器获取或直接实例化) object repository = Activator.CreateInstance(assembly.GetType(repositoryFullName)!, dbContext)!; } catch (Exception) { throw; } return dtoEntity; }
步骤2:反射调用仓储方法
实例化后的仓储是object类型,无法直接调用泛型接口方法,需通过反射获取方法信息再执行:
// 接上面的代码,获取仓储实例后: // 获取GetList方法(如果方法有重载,需传入参数类型数组精准匹配) MethodInfo getListMethod = genericRepoInterface.GetMethod("GetList")!; // 调用方法,第一个参数是仓储实例,第二个参数是方法所需参数(无参则传null) var dataList = getListMethod.Invoke(repository, null);
完整优化代码
public T Create(T dtoEntity) { string entityClassName = dtoEntity.GetType().Name; string repositoryClassName = entityClassName + "Repository"; string repositoryFullName = $"{repositoryNamespace}{repositoryClassName}"; try { // 动态获取实体类型 string entityFullName = $"{entitiesNamespace}{entityClassName}"; Type entityType = assembly.GetType(entityFullName)!; // 构造泛型仓储接口类型 Type genericRepoInterface = typeof(IEntityBaseRepository<>).MakeGenericType(entityType); // 实例化仓储(按需传入构造函数参数,比如DbContext) object dbContext = // 替换为你的DbContext实例获取逻辑 object repository = Activator.CreateInstance(assembly.GetType(repositoryFullName)!, dbContext)!; // 反射调用GetList方法 MethodInfo getListMethod = genericRepoInterface.GetMethod("GetList")!; var dataList = getListMethod.Invoke(repository, null); // 后续业务逻辑处理... } catch (Exception ex) { // 可添加日志记录等异常处理逻辑 throw; } return dtoEntity; }
关键注意事项
- 若仓储构造函数有依赖参数(如
DbContext),Activator.CreateInstance必须传入对应参数,否则会触发构造函数找不到的异常。 - 当方法存在重载时,需使用
GetMethod的重载版本,传入参数类型数组来精准匹配目标方法。 - 确保动态获取的类型全名(包含程序集名称)完全正确,否则
Type.GetType或Assembly.GetType会返回null。
内容的提问来源于stack exchange,提问作者Grigore Dolghin
相关产品推荐
相关产品推荐

