Repository Pattern

From Logic Wiki
Jump to: navigation, search


Reporsitory pattern is a layer between application and data storage. With this pattern application doesn't need to know how to delete, update or write data to database.

In a nutshell

  • Get(id)
  • GetAll()
  • Find(predicate)
  • Add(obj)
  • AddRange(obj)
  • Remove(obj)
  • RemoveAll(obj)


Sample pattern

Interface

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;

 namespace Queries.Core.Repositories
  {
    public interface IRepository<TEntity> where TEntity : class
    {
        TEntity Get(int Id);
        IEnumerable<TEntity> GetAll();
        IEnumerable<TEntity> Find(Expression<Func<TEntity, bool>> predicate);

        void Add(TEntity entity);
        void AddRange(IEnumerable<TEntity> entities);

        void Remove(TEntity entity);
        void RemoveAll(IEnumerable<TEntity> entities);
        
    }
 }

Generic Implementation

using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Linq.Expressions;
using System.Web;
using Spv.Api.Core.IDataAccess;

namespace Spv.Api.Core.DataAccess
{
    public class Repository<TEntity> : IRepository<TEntity> where TEntity : class
    {
        protected readonly DbContext Context;

        
        public Repository(DbContext context)
        {
            Context = context;
        }

        public TEntity Get(int Id)
        {
            return Context.Set<TEntity>().Find(Id);
        }

        public IEnumerable<TEntity> GetAll()
        {
            return Context.Set<TEntity>().ToList();
        }

        public IEnumerable<TEntity> Find(Expression<Func<TEntity, bool>> predicate)
        {
            return Context.Set<TEntity>().Where(predicate);
        }

        public void Add(TEntity entity)
        {
            Context.Set<TEntity>().Add(entity);
        }

        public void AddRange(IEnumerable<TEntity> entities)
        {
            Context.Set<TEntity>().AddRange(entities);
        }

        public void Remove(TEntity entity)
        {
            Context.Set<TEntity>().Remove(entity);
        }

        public void RemoveAll(IEnumerable<TEntity> entities)
        {
            Context.Set<TEntity>().RemoveRange(entities);
        }
    }
}

Custom Repository Interface

using System.Collections.Generic;
using Spv.Api.Models;
using Spv.Models;

namespace Spv.Api.Core.IDataAccess
{
    public interface IDealRepository : IRepository<Deal>
    {
        IEnumerable<DealModel> GetAllDealModels();
        DealModel GetDealModelById(int id);
    }
}

Custom Repository

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Spv.Api.Core.IDataAccess;
using Spv.Api.Models;
using Spv.Models;

namespace Spv.Api.Core.DataAccess
{
    public class DealRepository : Repository<Deal>, IDealRepository
    {
        public DealRepository(SpvDbContext context) : base(context)
        {
        }
 
        IEnumerable<DealModel> IDealRepository.GetAllDealModels()
        {
            return SpvDbContext.Deals.Select(x=> new DealModel(x)).ToList();
        }

        public DealModel GetDealModelById(int id)
        {
            var deal = SpvDbContext.Deals.FirstOrDefault(x => x.Id == id);
            return deal == null ? null : new DealModel(deal);
        }

        public SpvDbContext SpvDbContext
        {
            get { return Context as SpvDbContext;}
        }
    }
}

useful paging sample which can be implemented in custom repository

public IEnumerable<Deal> GetSomeDeals(int pageIndex, int pagesSize = 10)
{
 return SpvDbContext.Deals
  .Include(c => c.Author)
  .OrderBy(c => c.Name)
  .Skip((pageIndex - 1) * pageSize)
  .Take(pageSize)
  .ToList();
}

Generic Repository Pattern

GenericRepository.JPG



See Also : Unit Of Work Pattern