Repository and Unit of Work Pattern in ASP - Net MVC Application
Repository and Unit of Work Pattern in ASP - Net MVC Application
Introduction
In this article we will try to see what is Repository and Unit of Work Pattern in an ASP.NET MVC
application. We will also implement a small rudimentary sample application to understand the same.
Background
Possibility of using ORMs in our application saves us from a lot of code that needs to be written in
order to create our entities and data access logic. But using ORMs like entity framework sometimes
lead to scattered data access logic/predicates in various place in code.
Repository and Unit of work pattern provides a clean way to access data and at the same time
maintain the test-ablility of the application. Let us try to understand this by implementing a simple
ASP.NET MVC application.
Now we have the entity framework ready to be used in our application. We can very well use the
Context class in each controller to perform database operations. Let us try to see this by trying
to retrieve the data in our Index action of HomeController.
return View(books);
}
And when we try to run this application, we will see that it is getting the data from the database as:
Note: We will not be doing other CRUD operations here because they can be done on same lines
very easily.
Now there is nothing wrong from the code and functionality perspective in doing this. But there are
two problems in this approach.
1. The Data access code is scattered across the application and this is a maintenance nightmare.
2. The Action in the Controller is creating the Context inside itself. This makes this function non
testable using dummy data and we can never be able to verify the results unless we use test data.
Note: If the second point is not clear then it is recommended to read about Test Driven
Development using MVC. We cannot discuss it in this article otherwise the article will become
digressing.
Creating a Repository
Now how can we solve the problem. We can solve the problem by moving all the data access code
of entity framework in one place. So let us define a class that will contain all the data access logic for
Books
table.
But before creating this class, let us also think about the second problem for an instance. If we create
a simple interface defining the contract for accessing the books data and then implement this
interface in our proposed class, we will have one benefit. We can then have another class
implementing the same interface but playing around with the dummy data. Now as long as the
controller is using the Interface our test projects can pass the dummy data class and our controller
will not complain.
And the implementation of this class will contain the actual logic to perform the CRUD operations on
the Books table.
BooksRepository()
{
entities = new SampleDatabaseEntities();
}
#endregion
GC.SuppressFinalize(this);
}
~BooksRepository()
{
Dispose(false);
}
#endregion
}
Now let us create a simple Controller in which we will have the reference to this class being used
perform the CRUD operations on Books table.
public BooksController()
:this(new BooksRepository())
{
}
Now here in this above code when the application runs the default parameter-less constructor will
run which will create a BooksRepository object and it will be used in the class. The result of which
is that the application will be able to work with actual data from the database.
Now from our test project we will call the parameterized constructor with an object of the dummy
class containing dummy data. The benefit of which is that we should be able to test and verify the
controller classes using the dummy data.
Note: We will not be doing other CRUD operations here because they can be done on same lines
very easily.
Now imagine the scenario where we have multiple tables in the database. Then we need to create
multiple repositories in order to map the domain model to the data model. Now
having multiple repository classes poses on problem.
The problem is regarding the ObjectContext object. If we create multiple repositories, should they
contain their ObjectContext separately? We know that using multiple instances of
ObjectContext
object simultaneously can be a problem so should we really allow each repository to contain their
own instances?
To solve this problem. Why to let each Repository class instance have its own instance of
the ObjectContext. Why not create the instance of ObjectContext in some central location and
then pass this instance to the repository classes whenever they are being instantiated. Now this new
class will be called as UnitOfWorkand this class will be responsible for creating
the ObjectContext nstance and handing over all the repository instances to the controllers.
Unit Of Work
So let us create a separate Repository to which will be used via UnitOfWork class and
the ObjectContext will be passed to this class from outside.
Now this Repository class is taking the ObjectContext object from outside(whenever it is being
created). Also, we don't need to implement IDisposablehere because this class is not creating the
instance and so its not this class's responsibility to dispose it.
Now if we have to create multiple repositories, we can simply have all the repositories take the
ObjectContext
object at the time of construction. Now let us see how the UnitOfWork class creates the repository
and passes it on to the Controller.
GC.SuppressFinalize(this);
}
~UnitOfWork()
{
Dispose(false);
}
#endregion
}
Now we have a parameter-less constructor which will be called from controller default constructor
i.e. whenever our page runs. We also have a parameterized constructor which will be created from
test project and passed on to the controllers parameterized constructors.
The dispose pattern is now implemented by the UnitOfWork class because now it is responsible for
creating the ObjectContext so it should be the one disposing it.
public BookEnController()
: this(new UnitOfWork())
{
Now the test-ablity of this controller is still maintained by having the combination of default and
parameterized constructor. Also, the data access code is now centralized in one place with the
possibility of having multiple repository classes being instantiated at the same time. Let us run the
application.
Note: We will not be doing other CRUD operations here because they can be done on same lines
very easily.
And finally let us visualize our implementation with Unit of Work in place.
Point of interest
In this article we saw what is Repository and Unit of work pattern. We have also seen a rudimentary
implementation for the same in an ASP.NET MVC application. The next step to the project would be
to convert all the repository classes into one generic repository so that we don't need to create
multiple repository classes. I hope this has been informative.