Generic Repository Pattern With MVC

In this article, I am going to explain the generic repository pattern. We are going to start the concept and implementation of repository pattern, so first, let's try to understand what it is.

Why go with repository pattern?

Enterprise applications such as web-based enterprise applications, order management systems, payroll, accounting applications etc., are large-scale data flow applications. Along with data flow, they have some other features too.
  • Large amount of data
    These types (accounting, payroll, order management) of applications handle quite a large amount of data. And this amount of data is not fixed. It may vary day by day and get more and more than the previous day.

  • Separation of database and application
    Handling of data for an application is a major undertaking that needs some persistent storage. We usually separate the database engine from the application. Data object is a multiuser environment. At a given point in time, the data should be overwritten and given a concurrency feature.

  • Modification in business rules always acceptable
    Enterprise applications will always have new rules, so our application should be ready to accept those changes without affecting the past code and logics. These rules can change at any time. At the time of business upgradation, our application should be ready to accept all the changes. Sometimes, business rules have operations which usually deal with the size (data) and displaying the data in many pages or one page, we may have to display the data from different tables.
We come across these scenarios daily and reach one conclusion, that is,

Enterprise applications function in three different areas
  1. Data Access
    This layer deals with the data storage and retrieval, such as CRUD (Create, Read, Update, Delate)

  2. Business Rule
    This layer deals with data access such as reading and writing data and encapsulation with business-specific rules

  3. User Interface
    Displays the data to the end user and also accept input from the end user.
We use repository pattern when the scenario is dealing with a complex set of queries from multiple tables, to avoid the duplication so that we will not write the same code at multiple places.

In these scenarios, we use a layer between our domain class and data access layer. This layer will take care of all operations that can be reused again and again. In short, we can say that "Repository pattern plays a mediator's role in between the data-access layer and all the system."

Once the repository pattern is implemented, the client code won’t invoke the data-access directly. Instead, we will invoke the repository to get the job done. The repository offers a collection interface by providing methods to add, modify, remove, and fetch domain objects.

Let’s try to implement generic repository pattern in ASP MVC application.

  1. mvc 4
  2. sql server
  3. entity framework (code first approach)
Before going to the implementation part, it is a very common question usually asked by many developers - Entity Framework is already developed in repository pattern. Then, why will we again create a repository pattern?

I am trying to answer that.

In a small application, it is not required at all, but in enterprise applications, it is beneficial.
  1. Promoting loose coupling
    In repository pattern, all query code is isolated from the Entity Framework objects, so that it gives a good way to implement loose coupling with other model classes.

  2. Preventing Entity Framework objects from business logic layers
    Giving all data-access (Entity Framework objects) to the business layer is not a good idea. All LINQ queries get embedded inside it, these things are not desirable.
Steps to implement generic repository in ASP.NET MVC.

Step 1 - Add a new MVC template

Choose an MVC template.

Step 2 - Add Entity Framework

For this article, I am using 6.2.0 (stable).
Step 3

We are going to choose code first approach for creating a database and respective tables.
After defining the model class for students, now, we are going to make a schema class for the code-first approach.
  1. [Table("Students")]  
  2.    public class Student  
  3.    {  
  4.        [Key]  
  5.        [Display(Name ="Student Id")]  
  6.        public int StId { getset; }  
  7.        [Required]  
  8.        [Display(Name = "Student Name")]  
  9.        public string StName { getset; }  
  10.        [Display(Name = "Address")]  
  11.        public string StAddress { getset; }  
  12.        [Required]  
  13.        [Display(Name = "Mobile No.")]  
  14.        public string MobileNo{ getset; }  
  16.    }  
Step 4 - Create studentConext
Step 5 - Add database set Initializer

Usually, in Entity Framework, there are four different ways to create Initializer.
  • CreateDatabaseIfNotExists
    This is the default initializer and it will create the database if it does not exist already, as per the configuration. One more thing; it will throw an exception if the model class is changed and will try to run the application with this initializer.

  • DropCreateDatabaseIfModelChanges
    According to this initializer, it drops an existing database and creates a new database if model classes (entity classes) is changed.

  • DropCreateDatabaseAlways
    According to this initializer, it drops an existing database every time when we run the application. It doesn’t worry about the model class changes. This is useful when we want a fresh database every time we run the application.

  • Custome db Initilizer
    We can create our own custom initializer.

    1. public class SchoolDataBaseInitializer : CreateDatabaseIfNotExists<StudentContext>  
    2.     {  
    3.         protected override void Seed(StudentContext context)  
    4.         {  
    5.             base.Seed(context);  
    6.         }  
    8.     }  
For this application, I am implementing DropCreateDatabaseIfModelChanges database initializer method, in global.aspx file.
  1. public class MvcApplication : System.Web.HttpApplication  
  2.     {  
  3.         protected void Application_Start()  
  4.         {  
  5.             AreaRegistration.RegisterAllAreas();  
  6.             FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);  
  7.             RouteConfig.RegisterRoutes(RouteTable.Routes);  
  8.             BundleConfig.RegisterBundles(BundleTable.Bundles);  
  9.             Database.SetInitializer<StudentContext>(new DropCreateDatabaseIfModelChanges<StudentContext>());  
  10.         }  
  11.     }  
Step 6 - Now working with Generic Repository

Step 6.1 - Add an Interface.
  1. public  interface IGenericRepo<T> where T :class  
  2.     {  
  3.         IEnumerable<T> GetAll();  
  4.         T GetById(int id);  
  5.         void Insert(T obj);  
  6.         void Update(T obj);  
  7.         void Delete(int id);  
  8.         void Save();  
  9.     }  
As we can see Interface is very simple and easy to understand here, Here <T> I took to incorporate with any classes whoever needed.
Inside Interface, we are implementing two type parameters - T1, (type parameter is a concept which is taken in C++ for making the generic concept). Here, I am not telling both are same.T1 type parameter specifies the class type, which means that we pass the class while implementing the generic interface to any class, and on the other hand, I haven’t specified the T2 with any datatype, the reason is that - it might be any class having unique id in different type (might be int, string or all).

Step 6.2 - Implement the generic repository with Entity Framework

  1. public class GenericRepo<T> : IGenericRepo<T> where T : class  
  2.     {  
  3.         private StudentContext _context = null;  
  4.         private DbSet<T> table = null;  
  5.         public GenericRepo()  
  6.         {  
  7.             this._context = new StudentContext();  
  8.             table = _context.Set<T>();  
  9.         }  
  10.         public GenericRepo(StudentContext _context)  
  11.         {  
  12.             this._context = _context;  
  13.             table = _context.Set<T>();  
  14.         }  
  15.         public IEnumerable<T> GetAll()  
  16.         {  
  17.             return table.ToList();  
  19.         }  
  20.         public T GetById(int id)  
  21.         {  
  22.             return table.Find(id);  
  23.         }  
  24.         public void Insert(T obj)  
  25.         {  
  26.             table.Add(obj);  
  27.         }  
  28.         public void Update(T obj)  
  29.         {  
  30.             table.Attach(obj);  
  31.             _context.Entry(obj).State = EntityState.Modified;  
  32.         }  
  33.         public void Delete(int id)  
  34.         {  
  35.             T existing = table.Find(id);  
  36.             table.Remove(existing);  
  37.         }  
  38.         public void Save()  
  39.         {  
  40.             _context.SaveChanges();  
  41.         }  
  43.     }  

Now, it is very easy to implement the controller class to play with CRUD operation with Repository class. As the code stated that first we are crating a private memeber of our context class, and assigning to null. same as with the Dbset.

Two constructor I created, as default and paramterired for initilizing the context. as of the context is get initilize we will able to call implemented Generic methods.

Have a look at the fetch and insert records using Controller class.
  1. public class HomeController : Controller  
  2.    {  
  3.        private IGenericRepo<Students> repository = null;  
  5.        public HomeController()  
  6.        {  
  7.            this.repository = new GenericRepo<Students>();  
  8.        }  
  10.        public HomeController(IGenericRepo<Students> repository)  
  11.        {  
  12.            this.repository = repository;  
  13.        }  
  14.        public ActionResult Index()  
  15.        {  
  16.            var obj = repository.GetAll();  
  17.                return View(obj);  
  18.        }  
  19.        [HttpGet]  
  20.        public ActionResult AddStudent()  
  21.        {  
  22.            return View();  
  23.        }  
  24.        [HttpPost]  
  25.        public ActionResult AddStudent(Students obj)  
  26.        {  
  27.            repository.Insert(obj);  
  28.            return RedirectToAction("Index");  
  29.        }  
  30.    }  


This article explained the generic repository pattern, this approach were we can handle multiple database with a single implemented class, only we have to pass the respected class for operating the desired result.We have aslo seen the pros and cons of generic repository pattern.

Similar Articles