将泛型类型传递给通用接口

cul*_*rer 3 .net c# generics entity-framework interface

我正在尝试实现一个完全通用的CRUD API,通过上下文可以传入任何类类型并通常保存,更新等.

我有一个存储库,可以保存任何模型类型,如下所示:

public class Repository<T> : IRepository<T> where T : class 
    {
        private Context _db = new Context();

        public T Add(T newItem) 
        {
            var result = _db.Set<T>().Add((T)newItem);
            _db.SaveChanges();

            return result;
        }
    }
Run Code Online (Sandbox Code Playgroud)

这继承自实现所有"add"方法的通用接口:

public interface IRepository<T> where T : class
{
    T Add(T newItem);
}
Run Code Online (Sandbox Code Playgroud)

我很难理解为什么我不能将泛型类型传递给存储库接口的新实例?我理想的喜欢这样的东西:

var data = new Data(){
    Id = 1
};

IRepository<data.GetType()> repo = new Repository<data.GetType()>();
Run Code Online (Sandbox Code Playgroud)

从而允许我将任何类型传递给方法并在其后面生成正确的接口.

它允许我传递一种具体的类型,但这种类型会使其成为通用的对象.

任何关于这个的想法或解释为什么它不可能将不胜​​感激 - 谢谢.

hai*_*770 7

尝试在自身上实现具有泛型参数的通用存储库IRepository没有意义,因为术语泛型(在这种情况下)不是指CLR泛型,而是指存储库的性质,即使用不同类型的能力使用相同存储库实例的实体,与每个类型的存储库方法(ProductsRepository例如)相比.

将泛型参数放在方法上可以轻松解决问题:

public interface IRepository
{
     T GetById<T>(object id);
     IEnumerable<T> Get<T>(Expression<Func<T, bool>> criteria);
     T Add<T>(T data);
}
Run Code Online (Sandbox Code Playgroud)

使用EntityFramework可能的实现方式是:

public class EntityFrameworkRepository : IRepository
{
    public T GetById<T>(object id)
    {
        return this.Set<T>().Find(id);
    }

    public IEnumerable<T> Get<T>(Expression<Func<T, bool>> criteria)
    {
        return this.Set<T>().Where(criteria);
    }

    public T Add<T>(T data)
    {
        this.Set<T>().Add(data);
        return data;
    }
}
Run Code Online (Sandbox Code Playgroud)