简体   繁体   English

如何使用反射创建具有已定义参数的通用对象

[英]How can I create a generic object with defined parameters using reflection

I am trying to build a generic base class for an Entity Framework Repository and UnitOfWork class. 我正在尝试为实体框架存储库和UnitOfWork类构建通用基类。 I have defined by base repository class as follows: 我已经通过基本存储库类定义了如下:

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
}

I can create typed instance of the repository as follows: 我可以创建存储库的类型化实例,如下所示:

var ctx = new ProductContext();
var db = new EntityRepository<ProductContext, Product>(ctx);

Although, in practice, a type specific repository would be created for each class in the data context, for example... 尽管实际上,将为数据上下文中的每个类创建特定于类型的存储库,例如...

public class ProductDb
    : EntityRepository<ProductContext, Product>
{
    public ProductDb(ProductContext context)
        : base(context)
    {
    }

} }

This all seems to work as expected. 这一切似乎都按预期工作。 My problem lies in my generic UnitOfWork base class. 我的问题在于我的通用UnitOfWork基类。 Previously, I have manually defined each repository property in the UnitOfWork implementation, but I would like to automate this by using a hashtable and reflection (similar to that described in Long Le's Blog ) 以前,我已经在UnitOfWork实现中手动定义了每个存储库属性,但是我想通过使用哈希表和反射来自动执行此操作(类似于Long Le的Blog中所述 )。

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];
    }
}

When I run this code it fails with the error message: 当我运行此代码时,它失败并显示错误消息:

Product is not a GenericTypeDefinition.MakeGenericType 产品不是GenericTypeDefinition.MakeGenericType

Can anyone point me in the right direction to resolve this problem, or to put the question another way, how can I create a new instance of my EntityType using reflection? 任何人都可以为我指出正确的方向来解决此问题,或者换个角度提出问题,如何使用反射创建EntityType的新实例?

Thanks. 谢谢。

Thats because you are getting the wrong type. 那是因为您输入了错误的类型。 This is wrong because it gets the type of a generic instance. 这是错误的,因为它获取通用实例的类型。

var repositoryType = typeof(EntityRepository<CContext, TEntity>);

Use this instead to get the type of the generic. 使用它代替获取泛型的类型。

var repositoryType = typeof(EntityRepository<,>);

Also you need to change this 你也需要改变这个

var repositoryInstance = Activator.CreateInstance(
                repositoryType.MakeGenericType(typeof(CContext>,typeof(TEntity))
             );

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM