如何使用反射创建具有已定义参数的通用对象
本文关键字:参数 对象 定义 反射 何使用 创建 | 更新日期: 2023-09-27 17:56:04
我正在尝试为实体框架存储库和 UnitOfWork 类构建一个通用基类。 我按基本存储库类定义如下:
public class EntityRepository<CContext, TEntity>
where TEntity : class
where CContext : DbContext
{
protected readonly CContext _DbContext;
protected readonly DbSet<TEntity> _DbSet;
public EntityRepository(CContext context)
{
this._DbContext = context;
this._DbSet = context.Set<TEntity>();
}
// Implementation details go here
}
我可以创建存储库的类型化实例,如下所示:
var ctx = new ProductContext();
var db = new EntityRepository<ProductContext, Product>(ctx);
尽管在实践中,将为数据上下文中的每个类创建一个特定于类型的存储库,例如......
public class ProductDb
: EntityRepository<ProductContext, Product>
{
public ProductDb(ProductContext context)
: base(context)
{
}
}
这一切似乎都按预期工作。 我的问题在于我的通用 UnitOfWork 基类。 以前,我已经在 UnitOfWork 实现中手动定义了每个存储库属性,但我想通过使用哈希表和反射来自动化此操作(类似于 Long Le 博客中描述的)。
public class UnitOfWork<CContext>
where CContext : DbContext
{
protected readonly CContext _Context;
protected readonly Hashtable _Repositories;
public UnitOfWork(CContext context)
{
this._Context = context;
this._Repositories = new Hashtable();
}
public EntityRepository<CContext, TEntity> Repository<TEntity>()
where TEntity : class
{
var type = typeof(TEntity).Name;
if (!_Repositories.ContainsKey(type))
{
var repositoryType = typeof(EntityRepository<CContext, TEntity>);
var repositoryInstance = Activator.CreateInstance(
repositoryType.MakeGenericType(typeof(TEntity))
);
_Repositories.Add(type, repositoryInstance);
}
return (EntityRepository<CContext, TEntity>)_Repositories[type];
}
}
当我运行此代码时,它失败并显示错误消息:
Product 不是 GenericTypeDefinition.MakeGenericType
谁能指出我解决这个问题的正确方向,或者以另一种方式提出问题,如何使用反射创建我的 EntityType 的新实例?
谢谢。
那是因为你得到了错误的类型。这是错误的,因为它获取泛型实例的类型。
var repositoryType = typeof(EntityRepository<CContext, TEntity>);
请改用此选项来获取泛型的类型。
var repositoryType = typeof(EntityRepository<,>);
你还需要改变这个
var repositoryInstance = Activator.CreateInstance(
repositoryType.MakeGenericType(typeof(CContext>,typeof(TEntity))
);