Escolar Documentos
Profissional Documentos
Cultura Documentos
in
http://csharppulse.blogspot.in/2013/09/learning-mvc-part-6-generic-repository.html
Introduction
Creating a Generic Repository pattern in an MVC3 application with Entity Framework is the last topic that we are
about to cover in our journey of learning MVC.
The article will focus on Unit of Work Pattern and Repository Pattern, and shows how to perform CRUD operations
in an MVC application when there could be a possibility of creating more than one repository class. To overcome
this possibility and overhead, we make a Generic Repository class for all other repositories and implement a Unit
of Work pattern to provide abstraction.
Pre-requisites
There are few pre-requisites before we start with the article,
1. We have running sample application that we created in fifth part of the article series.
2. We have Entity Framework 4.1 package or DLL on our local file system.
3. We understand how MVC application is created (follow second part of the series).
We have already discussed what Repository Pattern is and why do we need Repository Pattern in our last article.
We created a User Repository for performing CRUD operations, but think of the scenario where we need 10 such
repositories.
Are we going to create these classes? Not good, it results in a lot of redundant code. So to overcome this
situation well create a Generic Repository class that will be called by a property to create a new repository thus
we do not result in lot of classes and also escape redundant code too. Moreover we save a lot of time that could
be wasted creating those classes.
situation is even worse if you need to keep track of the objects you've read so you can avoid inconsistent reads.
A Unit of Work keeps track and takes responsibility of everything you do during a business transaction that can
affect the database. When you're done, it figures out everything that needs to be done to alter the database as a
result of your work."
You see I dont have to concentrate much on theory, we already have great definitions existing, all we needed is
to stack them in a correct format.
using
using
using
using
using
using
System;
System.Collections.Generic;
System.Data;
System.Data.Entity;
System.Linq;
System.Linq.Expressions;
namespace LearningMVC.GenericRepository
{
public class GenericRepository<TEntity> where TEntity : class
{
internal MVCEntities context;
internal DbSet<TEntity> dbSet;
public GenericRepository(MVCEntities context)
{
this.context = context;
this.dbSet = context.Set<TEntity>();
}
public virtual IEnumerable<TEntity> Get()
{
IQueryable<TEntity> query = dbSet;
return query.ToList();
}
public virtual TEntity GetByID(object id)
{
return dbSet.Find(id);
}
public virtual void Insert(TEntity entity)
{
dbSet.Add(entity);
}
public virtual void Delete(object id)
{
TEntity entityToDelete = dbSet.Find(id);
Delete(entityToDelete);
}
public virtual void Delete(TEntity entityToDelete)
{
if (context.Entry(entityToDelete).State ==
EntityState.Detached)
{
dbSet.Attach(entityToDelete);
}
dbSet.Remove(entityToDelete);
}
public virtual void Update(TEntity entityToUpdate)
{
dbSet.Attach(entityToUpdate);
context.Entry(entityToUpdate).State = EntityState.Modified;
}
}
}
We can see, we have created the generic methods and the class as well is generic, when instantiating this class
we can pass any model on which the class will work as a repository and serve the purpose.
TEntity is any model/domain/entity class. MVCEntities is our DBContext as discussed in earlier parts.
Step 3: Implementing UnitOfWork: Create a folder named UnitOfWork under LearningMVC project, and add a
class UnitOfWork.cs to that folder.
The code of the class is as follows:
using System;
using LearningMVC.GenericRepository;
namespace LearningMVC.UnitOfWork
{
public class UnitOfWork : IDisposable
{
private MVCEntities context = new MVCEntities();
private GenericRepository<User> userRepository;
public GenericRepository<User> UserRepository
{
get
{
if (this.userRepository == null)
this.userRepository = new GenericRepository<User>
(context);
return userRepository;
}
}
public void Save()
{
context.SaveChanges();
}
private bool disposed = false;
protected virtual void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
context.Dispose();
}
}
this.disposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
}
We see the class implements IDisposable interface for objects of this class to be disposed.
We create object of DBContext in this class, note that earlier it was used to be passed in Repository class from
a controller.
Now it's time to create our User Repository. We see in the code itself that, simply a variable named
userRepositoryis declared as private GenericRepository userRepository; of type
GenericRepository serving User entity to TEntity template.
Then a property is created for the same userRepository variable in a very simplified manner,
public GenericRepository<User> UserRepository
{
get
{
if (this.userRepository == null)
this.userRepository = new GenericRepository<User>
(context);
return userRepository;
}
}
I.e., mere 6-7 lines of code. Guess what? Our UserRepository is created.
Now this unitOfWork instance of UnitOfWork class holds all th repository properties,if we press ." After it, it will
show the repositories.So we can choose any of the repositories created and perform CRUD operations on them.
E.g. our Index action:
Here,
unitOfWork.UserRepository > Accessing UserRepository.
unitOfWork.UserRepository.Get() -> Accessing Generic Get() method to get all users.
Earlier we used to have MyController constructor like:
public MyController()
{
this.userRepository = new UserRepository(new
MVCEntities());
}
Now, no need to write that constructor, in fact you can remove the UserRepository class and Interface we
created in part 5 of Learning MVC.
I hope you can write the Actions for rest of the CRUD operations as well.
Details
Create:
[HttpPost]
public ActionResult Create(LearningMVC.Models.UserList userDetails)
{
try
{
var user = new User();
if (userDetails != null)
{
user.UserId = userDetails.UserId;
user.FirstName = userDetails.FirstName;
user.LastName = userDetails.LastName;
user.Address = userDetails.Address;
user.PhoneNo = userDetails.PhoneNo;
user.EMail = userDetails.EMail;
user.Company = userDetails.Company;
user.Designation = userDetails.Designation;
}
unitOfWork.UserRepository.Insert(user);
unitOfWork.Save();
return RedirectToAction("Index");
}
catch
{
return View();
}
}
Edit:
Delete:
Conclusion
We now know how to make generic repositories too, and perform CRUD operations using it.
We have also learnt UnitOfWork pattern in detail. Now you are qualified and confident enough to apply these
concepts in your enterprise applications. This was the last part of this MVC series, let me know if you feel to
discuss any topic in particular or we can also start any other series as well. For more informative articles,visit my
blog A Practical Approach .
Happy coding :-).