Thursday, 19 December 2013

What is Repository and Unit of Work Patterns in Asp.Net MVC

previous Topic with MVC 

First question that comes in our minds is why there are so many layers of code. Here are the major reasons that repository and unit of work patterns are intended to create an abstraction layer between the data access layer and the business logic layer of an application. Implementing these patterns can help insulate your application from changes in the data store and can facilitate automated unit testing or test-driven development (TDD).

Repositories are the single point where we hand off and fetch objects. It is also the boundary where communication with the storage starts and ends.

Repository contains all the "real" implementations to manipulate and expose data
Model contains model classes. MVC project contains Controllers and Views.

ASP.Net MVC Project
  • Controller - just routes the calls and has no business logic inside means The Controller handles the input (to the database records).
  • View - The View displays the data (the database records).
  • Model- the Model represents the application core (for instance a list of database records).
Repository Project
  • Repository classes - uses DB and exposes data. Entity Frame code first strategy has been used to generate data access layer.
  • Repository interfaces - define the methods to be called from the Controller 
Unit of work is a pattern to handle transaction during data manipulation using the Repository pattern. So we can say, according to Martin Fowler, Maintains a list of objects affected by a business transaction and coordinates the writing out of changes and the resolution of concurrency problem.
The important responsibilities of Unit of Work are,
  • To manage transactions.
  • To order the database inserts, deletes, and updates.
  • To prevent duplicate updates. Inside a single usage of a Unit of Work object, different parts of the code may mark the same Invoice object as changed, but the Unit of Work class will only issue a single UPDATE command to the database.

Why we use Repository and Unit of Work Patterns in Asp.Net MVC

  • Maintainability and extensibility through Separations of concerns
  •  Code quality through Testability
  •  Productivity through Loose coupling


Practicle Implementation with Repository Concept in Asp.Net MVC

-- Execute this query for Sql Server
use TestDb
create table Student(SrNo int primary key,Name nvarchar(50),Course nvarchar(50),Age int not null,MobileNo nvarchar(50))

First we create class which name is Cetpa.cs……………..

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
//using this  namespace................
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace MvcApplicationRepository.Models
{
[Table("Student")]
public class Cetpa
{
// Field SrNo is primary key  in table
[Key]
[DatabaseGenerated(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.None)]
public int SrNo { get; set; }
public string Name { get; set; }
public string Course { get; set; }
//because Age Field is not null in sql server
public int? age { get; set; }
public string MobileNo { get; set; }
}
}

Note: Because you are not using Model1.edmx in your MVCAppliction that’s why create class in Models which name is Cetpa.cs

Then we create class which name is database.cs……………..

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Entity;
namespace MvcApplicationRepository.Models
{
public class database:DbContext
{
public database()
: base("MyConnection")
{
}
// Note this MyConnection is declare in Web.config  with connectionstring


public DbSet<Cetpa> cetpa { get; set; }
}
}

Next step go to Global.asax in write code in Application_strat() section….

Database.SetInitializer<MvcApplicationRepository.Models.database>(null);



Then after we create an Interface which name is IRepository.cs………………..
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MvcApplicationRepository.Models
{
public interface IRepository
{
List<Cetpa> getdata();
void Insert(Cetpa c);

}
}
Next step we create a class which name is Repository.cs which implement IRepository interface………………..
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace MvcApplicationRepository.Models
{
    public class Repository:IRepository
    {
        database d = new database();
        public List<Cetpa> getdata()
        {
            return d.cetpa.ToList();
        }
        public void Insert(Cetpa c)
        {
            d.cetpa.Add(c);
            d.SaveChanges();
         
        }
       
    }
}
Code for HomeController.cs……………………………………………..
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using MvcApplicationRepository.Models;

namespace MvcApplicationRepository.Controllers
{

public class HomeController : Controller
{
//
// GET: /Home/
IRepository i1;
public HomeController()
{
i1 = new Repository();
}
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Index(Cetpa c)
{
try
{
i1.Insert(c);
ViewData["message"] = "Save Successfully";

}
catch (Exception ex)
{
ViewData["error"] =ex.Message;
}
return View();
}

}
}
Code for Index.cshtml……………………………………………..
@model MvcApplicationRepository.Models.Cetpa

@{
Layout = null;
}

<!DOCTYPE html>

<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
</head>
<body>
<script src="~/Scripts/jquery-1.7.1.min.js"></script>
<script src="~/Scripts/jquery.validate.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>

@using (Html.BeginForm()) {
@Html.ValidationSummary(true)

<fieldset>
<legend>Cetpa</legend>
<div class="editor-label">
@Html.LabelFor(model => model.SrNo)
</div>
<div class="editor-field">
@Html.TextBoxFor(model => model.SrNo)
@Html.ValidationMessageFor(model => model.SrNo)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Name)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Name)
@Html.ValidationMessageFor(model => model.Name)
</div>

<div class="editor-label">
@Html.LabelFor(model => model.Course)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Course)
@Html.ValidationMessageFor(model => model.Course)
</div>

<div class="editor-label">
@Html.LabelFor(model => model.age)
</div>
<div class="editor-field">
@Html.TextBoxFor(model => model.age)
@Html.ValidationMessageFor(model => model.age)
</div>

<div class="editor-label">
@Html.LabelFor(model => model.MobileNo)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.MobileNo)
@Html.ValidationMessageFor(model => model.MobileNo)
</div>

<p>
<input type="submit" value="Create" />


</p>
<div style="color:red;"> @ViewData["error"]</div>
<div style="color:green;"> @ViewData["message"]</div>
</fieldset>
}

<div>
@Html.ActionLink("Back to List", "Index")
</div>
</body>
</html>

Result:



1 comments: