在存储库中实现泛型类型

时间:2013-11-09 19:15:43

标签: c# generics interface implementation

我不确定我想做什么是可能的,因为我在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<ContentPages>作为参数类型,我只想让它采用IRepository

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

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

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

总而言之,我希望我使用界面而不用表示类型,所以它从实际对象中获取类型

public constructor1(IRepository ContentRepository){}

下一个控制器获取此构造函数

public constructor2(IRepository BlogRepository){}

等等

我希望我能够足够接近地描述我的问题,让你们明白:)

2 个答案:

答案 0 :(得分:0)

IRepository类的具体实现中,您可以按如下方式定义TEntity的类型。

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

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

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

答案 1 :(得分:0)

尝试这样的变体:

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