Generic Repository Pattern With MVC

In this article we will going to learn how to implement Generic Repository pattern, along with we will check some aspects of them while implementing.

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.

Prerequisites
  1. asp.net 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; }  
  15.   
  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.

    Syntax
    1. public class SchoolDataBaseInitializer : CreateDatabaseIfNotExists<StudentContext>  
    2.     {  
    3.         protected override void Seed(StudentContext context)  
    4.         {  
    5.             base.Seed(context);  
    6.         }  
    7.   
    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.
 
Inside Interface, we are implementing two type parameters - T1, and T2, (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 : IGeneric<Student, int>,IDisposable  
  2.    {  
  3.        private StudentContext db;  
  4.        public GenericRepo()  
  5.        {  
  6.            this.db = new StudentContext();  
  7.        }  
  8.        public List<Student> SelectAll()  
  9.        {  
  10.            return db.Students.ToList();  
  11.        }  
  12.        public Student SelectByID(int id)  
  13.        {  
  14.            return db.Students.Where(x => x.StId == id).SingleOrDefault();  
  15.        }  
  16.         
  17.        public void Insert(Student obj)  
  18.        {  
  19.            db.Students.Add(obj);  
  20.        }  
  21.        public void Update(Student obj)  
  22.        {  
  23.            db.Entry(obj).State = System.Data.Entity.EntityState.Modified;  
  24.        }  
  25.        public void Delete(int id)  
  26.        {  
  27.            Student obj = db.Students.Where(x => x.StId == id).SingleOrDefault();  
  28.            db.Students.Remove(obj);  
  29.        }  
  30.        public void Save()  
  31.        {  
  32.            db.SaveChanges();  
  33.        }  
  34.        public void Dispose()  
  35.        {  
  36.            db.Dispose();  
  37.        }  
  38.        
  39.    }  
Now, it is very easy to implement the controller class to play with CRUD operation with Repository class.

Have a look at the fetch and insert records.
 
Summary

This article explained the generic repository pattern implementation in MVC application along with the pros and cons.