Diving in OOP (Day 3): Polymorphism and Inheritance (Dynamic Binding/Run Time...
Repository Pattern in MVC3 Application with Entity Framework
1. Learning MVC-Part 5
Repository Pattern in MVC3 Application with Entity Framework
Introduction:
In our last four articles, we learnt almost everything about how to create a MVC application
and how to communicate with database using the sameapplication.
In the third part of Learning MVC, we learnt communication between MVC application and
Databaseusing EntityFramework, so referring to the same context, In this article I’ll focus on
how to implement a Repository Pattern in the sameMVC application, therefore moving ahead
a step towards architecturalapproach of developing an enterpriseapplication.
Our Roadmap:
Just to remind our full roadmap towards learning MVC,
Part1: Introduction to MVC architecture and Separation of Concerns.
Part 2: Creating MVC Application from scratch and connecting it with databaseusing LINQ to
SQL.
Part 3: Connecting the MVC Application with the help of EntityFramework DB-Firstapproach.
Part 4: Connecting the MVC Application with the help of EntityFramework Code-First
approach.
Part 5: Implementing Repository PatterninMVC ApplicationwithEntityFramework.
Part 6: Implementing a generic Repository Pattern and Unit Of Work pattern in MVC
Application with EntityFramework.
Pre-requisites:
There are few pre-requisites beforewe start with the article,
1. We haverunning sample application that we created in third part of the article series.
2. We haveEntityFramework 4.1 packageor dll on our local file system.
3. We understand how MVCapplication is created.
Repository Pattern:
Very few authors explain the concept and jump directly over the practical implementation of
the pattern. So, firstlet us understand what is repository pattern? , why should we use it?
In simple terms, a repository basically works as a mediator between our business logic layer
and our data access layer of the application. Sometimes it would be troublesometo expose
the data access mechanism directly to business logic layer, it may resultin redundantcode for
accessing data for similar entities or it may result in a code that is hard to test or understand.
2. To overcomethese kinds of issues, and to write an Interfacedriven and test driven code to
access data, we useRepository Pattern. Therepository makes queries to the data sourcefor
the data, thereafter maps the data from the data sourceto a business entity/domain object,
finally and persists the changes in the business entity to the data source. According to MSDN,
A repository separatesthe business logic from the interactionswith the underlying data source
or Web service. The separation between the data and business tiers has three benefits:
It centralizesthe data logic or Web service access logic.
It providesa substitution point for the unit tests.
It providesa flexible architecture thatcan be adapted as the overall design of the
application evolves.
When we useEntity Framework, as wedid in our last application created, we were calling the
Entity Framework class objectin the controller class for accessing the entity classes. Now we
can say that that systemwas somewhata tightly coupled system.To overcomethis situation,
as we discussed, we’llimplement Repository Pattern.
In Repository, wewrite our wholebusiness logic of CRUD operations with the help of Entity
Framework classes, thatwill not only resultin meaningfultest driven code but will also reduce
our controller code of accessing data.
Creating Repository:
Creating Repository is not that tough at it sounds to be, once you implement this by your own,
you’ll love it.
Step1: Open up our existing MVC3 application in VisualStudio, that we created in third part to
ineteract with databasewith the help of Entity Framework.
Step2: Create a folder named Repository and add an Interfaceto that folder named
IUserRepository , this interface we derive fromIDisposabletypeof interface.
We’ll declare methods for CRUD operations on User entity class over here, you can choosethe
names of the method as per your choice, but those should be easy to understand and follow.
Like I used in the below code of my interface,
using System;
using System.Collections.Generic;
namespace LearningMVC.Repository
{
public interface IUserRepository:IDisposable
3. {
IEnumerable<User> GetUsers();
User GetUserByID(int userId);
void InsertUser(User user);
void DeleteUser(int userId);
void UpdateUser(User user);
void Save();
}
}
We can see each method name signifies particular CRUD operation on User entity.
User Entity is the same entity we generated in Model.tt class in Part3 of learning MVC,
remember?????? .
Step3 : Extract a class fromthat interface and call it UserRepository. This UserRepository class
will implement all the methods of that interface, but with the help of Entity Framework.Now
here comes the use of our DBContext class MVCEntities, we already havethis class in our
existing solution, so we don’t haveto touch this class, simply, write our business logic in the
interface methods implemented in UserRepository Class,
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
namespace LearningMVC.Repository
{
public class UserRepository:IUserRepository
{
private MVCEntities context;
public UserRepository(MVCEntities context)
{
this.context = context;
}
public IEnumerable<User> GetUsers()
{
return context.Users.ToList();
}
public User GetUserByID(int userId)
4. {
return context.Users.Find(userId);
}
public void InsertUser(User user)
{
context.Users.Add(user);
}
public void DeleteUser(int userId)
{
User user = context.Users.Find(userId);
context.Users.Remove(user);
}
public void UpdateUser(User user)
{
context.Entry(user).State = EntityState.Modified;
}
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);
6. 90 % of the job is done now. Now the only thing left is to use this repository in our controller.
This is needless to explain how you’ll call repository insidethe controller, as you now know
how to treat our controller, but still lets do it for once,
Step4:Go to the controller, declare the IUserRepositoryreference, and in the constructor
initialize the object with UserRepository class, passing MVCEntities to the constructor as
parameter we defined in UserRepository class,
#region Private member variables...
private IUserRepository userRepository;
#endregion
#region Public Constructor...
/// <summary>
/// Public Controller to initialize User Repository
/// </summary>
public MyController()
{
this.userRepository = new UserRepository(new MVCEntities());
}
#endregion
In solution this will look like,
7. Step5: Now for all the actions of the controller in which we were using Entity Framework
context directly, we replace the calling logic by the created userRepository object, and call
methods defined in repository class,
Like, in Indexcontroller, where we show the list of users, wedo,
var userList = from user in userRepository.GetUsers() select user;
var users = new List<LearningMVC.Models.UserList>();
if (userList.Any())
{
foreach (var user in userList)
{
users.Add(new LearningMVC.Models.UserList() {
UserId = user.UserId, Address = user.Address, Company = user.Company,
FirstName = user.FirstName, LastName = user.LastName, Designation =
user.Designation, EMail = user.EMail, PhoneNo = user.PhoneNo });
}
}
We can see the earlier code used remained same, only a layer has been introduced between
Entity Framework data access layer and business logic, and controller now only uses that
abstracted layer to communicate with database.
10. Delete:
Step6: Run the application, and we see application running as it was earlier,
Now that’s party time.
11. Conclusion
We now know how to make repositories too, and performCRUD operations using it.
Now we can visualizethat how useful the pattern is and how it solved our issues of tight
coupling and resulted in an appropriatearchitecture,
As per MSDN, Use the Repository pattern to achieve one or more of the following objectives:
You want to maximize the amount of code that can be tested with automation and to
isolate the data layer to supportunit testing.
You access the data sourcefrommany locations and wantto apply centrally managed,
consistentaccess rules and logic.
You want to implement and centralize a caching strategy for the data source.
You want to improvethe code's maintainability and readability by separating business
logic from data or service access logic.
You want to use business entities that are strongly typed so that you can identify
problems at compile time instead of at run time.
You want to associatea behavior with the related data. For example, you wantto
calculate fields or enforce complex relationships or business rules between the data
elements within an entity.
You want to apply a domain model to simplify complex business logic.
And I fully agree to it, but is our application made use of the pattern appropriately? What if
there are 100’s of Repositories that needs to be created? What if we have 100’s of entities? Do
we create Repositories for all of them, resulting in a mess and code redundancy? , the answer
is big NO. In my next and last article of the series, we’ll learn how to create a Generic
Repository to servethe purposeof n number of Entities. The sourcecode of this article and
existing article i.e. Part 3 along with database scripts has been attached, you can download
and run the solution, and drop me a question in caseyou feel so. I’llbe happy to answer.
Happy Coding :-).