如何通过字符串名称为GenericRepository创建对应实体类型实例?
解决通过字符串类型名创建GenericRepository实例的问题
你之前的反射代码错误在于MakeGenericType需要传入Type类型对象,而非字符串。以下是正确的实现步骤:
1. 将字符串类型名转换为Type对象
首先需要把"Customers"字符串转换成对应的类Type,注意必须指定完整的命名空间(类的全名):
string modelName = "Customers"; // 替换为你的模型类实际所在的命名空间 string fullTypeName = $"YourNamespace.Models.{modelName}"; // 方式1:通过Type.GetType获取(需确保类在当前程序集或已加载的程序集中) Type entityType = Type.GetType(fullTypeName); // 方式2:如果Type.GetType返回null,直接从程序集查找(更可靠) // Assembly assembly = Assembly.GetExecutingAssembly(); // 当前执行程序集 // Assembly assembly = Assembly.Load("YourAssemblyName"); // 指定程序集名称 // Type entityType = assembly.GetType(fullTypeName);
2. 创建泛型仓储实例
拿到正确的entityType后,即可构建泛型仓储类型并实例化:
if (entityType != null) { // 创建GenericRepository<T>的泛型类型 Type repositoryType = typeof(GenericRepository<>).MakeGenericType(entityType); // 实例化仓储对象 var repository = Activator.CreateInstance(repositoryType); // 可选:调用仓储方法(两种方式) // 方式A:通过非泛型接口转换(推荐) // 先定义非泛型IService接口,让泛型IService<T>继承它 if (repository is IService service) { var allData = service.GetAll(); } // 方式B:反射调用方法 MethodInfo getAllMethod = repositoryType.GetMethod("GetAll"); var allData = getAllMethod.Invoke(repository, null); } else { throw new ArgumentException($"无法找到类型:{fullTypeName}"); }
补充:非泛型接口定义示例
为了方便调用仓储方法,建议定义一个非泛型基础接口:
public interface IService { IEnumerable<object> GetAll(); // 按需添加其他通用方法 } public interface IService<T> : IService, IDisposable where T : class { new IEnumerable<T> GetAll(); // 你的泛型方法定义 } // 泛型仓储实现该接口 public class GenericRepository<TEntity> : IService<TEntity>, IDisposable where TEntity : class { public IEnumerable<TEntity> GetAll() { // 实现逻辑 } IEnumerable<object> IService.GetAll() { return GetAll().Cast<object>(); } // IDisposable实现及其他方法 }
内容的提问来源于stack exchange,提问作者Reza FerdosAra
相关产品推荐
相关产品推荐

