【问题标题】:Implementing a generic type in repository在存储库中实现泛型类型
【发布时间】:2013-11-21 19:33:54
【问题描述】:

我不确定我想做的事情是否可行,因为我在 google 上没有找到任何东西,经过大约 30 分钟的密集搜索后,我决定直接询问。

我已经为我的存储库定义了一个简单的接口

public interface IRepository<TEntity> : IDisposable
{
    TEntity GetById(object id);
    List<TEntity> GetAll();
}

现在我想实现我的第一个存储库,它的工作原理是这样的

public class ContentRepository : IRepository<ContentPages>
{
    private readonly Context _db = new Context();

    public ContentPages GetById(object id)
    {
        var result = _db.ContentPages.Find(id);
        return result;
    }

    public List<ContentPages> GetAll()
    {
        return _db.ContentPages.ToList();
    }

    public void Dispose()
    {
        _db.Dispose();
    }
}

这很好用,但是当我将存储库注入到我的 mvc 控制器时,它需要一个 IRepository&lt;ContentPages&gt; 作为参数类型,我只希望它采用一个 IRepository

我试图像这样将泛型类型移动到函数本身

public interface IRepository : IDisposable
    {
        TEntity GetById<TEntity>(object id);
        List<TEntity> GetAll<TEntity>();
    }
}

当我这样做时,我不知道如何在实现中定义我的泛型类型TEntity

所以总而言之,我希望我在不指定类型的情况下使用接口,因此它可以像这样从实际对象中获取类型

public constructor1(IRepository ContentRepository){}

下一个控制器得到这个构造函数

public constructor2(IRepository BlogRepository){}

等等

我希望我能把我的问题描述得足够详细,让你们理解:)

【问题讨论】:

    标签: c# generics interface implementation


    【解决方案1】:

    试试这样的变种:

    public interface IRepository<TEntity> where TEntity : class
    {
        TEntity Find(params object[] keyValues);
    
        // ...
    }
    
    public class Repository<TEntity> : IRepository<TEntity> where TEntity : class
    {
        private readonly IDbSet<TEntity> _dbSet;
    
        public Repository(IDbContext context)
        {
            _dbSet = context.Set<TEntity>();
        }
    
        public virtual TEntity Find(params object[] keyValues)
        {
            return _dbSet.Find(keyValues);
        }
    
        // ...
    }
    

    使用示例:

    IRepository<ApplicationUser> repository = new Repository<ApplicationUser>(new ApplicationDbContext());
    ApplicationUser applicationUser = repository.Find("key");
    

    此外,还有一个更好的解决方案 - 您可以使用模式 UnitOfWork。检查this implementation on codeplex。真的很酷。

    例子:

    public class DatabasesController : Controller
    {
        private UnitOfWork _unitOfWork;
        private WebContext _context;
    
        public DatabasesController()
        {
            _context = new WebContext();
            _unitOfWork = new UnitOfWork(_context);
        }
    
        //
        // GET: /Databases/
    
        public ViewResult Index()
        {
            List<Database> databases =
                _unitOfWork
                .Repository<Database>()
                .Query()
                .Include(database => database.FileEntitiesInfo)
                .Get()
                .ToList();
            _unitOfWork.Save();
            return View(databases);
        }
    }
    

    【讨论】:

      【解决方案2】:

      IRepository类的具体实现中,你可以定义TEntity的类型如下。

        public TEntity GetById<TEntity>(object id) where TEntity:class
         {
          // Implimetation
         }
      

      但在这里根据存储库模式更好地使用如下。

      public interface IRepository<TEntity>: IDisposable where TEntity : class 
      

      【讨论】:

      • 当我使用你的第一个例子并实现如下:return _db.ContentPages.Find(id);我无法将 ContentPages 转换为 TEntity 我不能说 Tentity:ContentPages 因为它违反了界面
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-06
      • 2020-05-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-28
      相关资源
      最近更新 更多