here or

Repository Pattern practice in data access layer via entity framework

To read about definitions of Repository patter refer to here or here and then let's begin! I'm gonna to show the using of repository pattern with entityframework in Data access layer. Sorry about the example because it's about product , category , brand , blah blah again! First of all create an interface called IAggregateRoot

  1.    public interface IAggregateRoot
  2.     {
  3.     }

It has no any member , you will find out what's that for later in this article , then create a generic type interface for introducing most common operation used in enterprise DAL such as CRUD …

  1.  public interface IRepository<T>
  2.     {
  3.         IEnumerable<T> GetAll();
  4.         T FindBy(params Object[] keyValues);
  5.         void Add(T entity);
  6.         void Update(T entity);
  7.         void Delete(T entity);
  8.         void SaveChanges();
  9.     }

Now create the Product class and derive it from or so called implement the IAggregateRoot member for it!

  1.     public class Product : IAggregateRoot
  2.     {
  3.         public Guid Id { get; set; }
  4.         public string Name { get; set; }
  5.         public decimal Price { get; set; }
  6.         public string Description { get; set; }
  7.         public DateTime CreationTime { get; set; }
  8.         public string Picture { get; set; }
  9.     }

And now create the IProductRepository interface like this :

  1.     public interface IProductRepository : IRepository<Product>
  2.     {
  3.     }

I have to notice that all we have done above are in Model layer if you are using layered application , now refer to your DAL or Repository layer and create your DbContextClass:

  1.    public class YourProjectContext : DbContext
  2.     {
  3.           public DbSet<Product> Product { get; set; }
  4.     }

And now create the GenericRepoitory class like this :

  1.     public class Repository<T> : IRepository<T> where T : class, IAggregateRoot
  2.     {
  3.         private readonly DbSet<T> _entitySet;
  4.         private readonly YourProjectContext _yourProjectContext ;
  5.         public Repository(YourProjectContext yourProjectContext )
  6.         {
  7.             _yourProjectContext = yourProjectContext ;
  8.             _entitySet = yourProjectContext .Set<T>();
  9.         }
  10.         public IEnumerable<T> GetAll()
  11.         {
  12.             return _entitySet;
  13.         }
  14.         public T FindBy(params Object[] keyValues)
  15.         {
  16.             return _entitySet.Find(keyValues);
  17.         }
  18.         public void Add(T entity)
  19.         {
  20.             _entitySet.Add(entity);
  21.         }
  22.         public void Update(T entity)
  23.         {
  24.             _entitySet.Attach(entity);
  25.            _yourProjectContext.Entry(entity).State=EntityState.Modified;
  26.         }
  27.         public void Delete(T entity)
  28.         {
  29.             var e = _yourProjectContext.Entry(entity);
  30.             if (e.State == EntityState.Detached)
  31.             {
  32.                 _yourProjectContext.Set<T>().Attach(entity);
  33.                 e = _yourProjectContext.Entry(entity);
  34.             }
  35.             e.State=EntityState.Deleted;   
  36.         }
  37.         public void SaveChanges()
  38.         {
  39.             _yourProjectContext.SaveChanges();
  40.         }
  41.     }

 you have all members of IRepository<T> implemented in this class , Now create the ProductRepository class like this :

  1.     public class ProductRepository :Repository<Product>,IProductRepository
  2.     {
  3.       public ProductRepository(YourProjectContext yourProjectContext)
  4.             : base(yourProjectContext)
  5.         {
  6.         }
  7.     }

Now by calling IProductRepository interface in service or application layer you have full access to whole generic method of Repository and also for all members of ProductRepository , for example spouse this service class

  1.     public class ProductService : IProductService
  2.     {
  3.         private readonly IProductRepository _productRepository;
  4.         public ProductService(IProductRepository productRepository)
  5.         {
  6.             _productRepository = productRepository;
  7.         }
  8.      }

You can access the repository members by _productRepository readonly field.

If want to create an specific method in ProductRepository such as FindAllProductsByCategory  you have to first define it in IProductRepository :

  1.     public interface IProductRepository : IRepository<Product>
  2.     {
  3.         IEnumerable<Product> FindAllProductsByCategory(Guid categoryId);
  4.     }

And Then in ProductRepository you have to implement the interface member

  1.     public class ProductRepository :Repository<Product>,IProductRepository
  2.     {
  3.         private readonly StatosContext _statosContext;
  4.         public ProductRepository(StatosContext statosContext)
  5.             : base(statosContext)
  6.         {
  7.             _statosContext = statosContext;
  8.         }
  9.         public IEnumerable<Product> FindAllProductsByCategory(Guid categoryId)
  10.         {
  11.             var query =
  12.                 _statosContext.Product.Where(p => p.Category.Id == categoryId).OrderByDescending(p => p.CreationTime);
  13.             return query.ToList();
  14.         }

Thanks for reading!

Question!  is there any need to use unitOfWork pattern when you using repository pattern with entity framework ??

Basically NOT because entityframework supports the UnitOfWork pattern and in other words entityfrmawork code first has been built based on UnitOfwork pattern and adding unitOfWork again is  typically redundant (because of using DbContext) , but if want to have more control over disposal of context you can write your own IDbContextFactory and implement the unitOfwork pattern ! Cheers


Tags: Design Pattern Entity Framework C#


comments powered by Disqus