Repository and Unit of Work

Содержание

Слайд 2

Repository and Unit of Work Design Patterns with Entity Framework

Repository and Unit of Work

Design Patterns
with Entity Framework

Слайд 3

Патерн Repository Патерн Unit of Work

Патерн Repository
Патерн Unit of Work

Слайд 4

Слайд 5

Repository Pattern Посередник між BLL та DAL(Data Source) рівнями Це рівень,

Repository Pattern

Посередник між BLL та DAL(Data Source) рівнями
Це рівень, який

роздвляє Дані та Рівень Domain
Слайд 6

Рівень абстракції між Business Logic рівнемта Data Access рівнем. Ізолює програму

Рівень абстракції між Business Logic рівнемта Data Access рівнем.
Ізолює програму від

змін джерела даних.
Полегшує автоматизоване юніт тестування, Test Driven Development.
Джерело даних може бути змінено без будь-яких змін в бізнес логіці і з мінімальними змінами в Репозиторії.
Легко створювати mock репозиторію.

Для чого потрібен Repositorie ?

Слайд 7

EF DbContext implementer public class SchoolContext : DbContext { public DbSet

EF DbContext implementer

public class SchoolContext : DbContext
{
public DbSet Courses {get;set;}

public DbSet Departments {get;set;}
public DbSet Enrollments {get;set;}
public DbSet Instructors {get;set;}
public DbSet Students {get;set;}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
//…
}
}
Слайд 8

IGenericRepository public interface IGenericRepository where TEntity : class { IEnumerable Get(

IGenericRepository

public interface IGenericRepository where TEntity : class
{
IEnumerable Get(

Expression> filter = null, Func, IOrderedQueryable> orderBy
= null,string includeProperties = "");
TEntity GetByID(object id);
void Insert(TEntity entity);
void Delete(object id);
void Delete(TEntity entityToDelete);
void Update(TEntity entityToUpdate);
}
Слайд 9

GenericRepository constructor public class GenericRepository : IGenericRepository where TEntity : class

GenericRepository constructor

public class GenericRepository : IGenericRepository where TEntity : class
{


internal SchoolContext context;
internal DbSet dbSet;
public GenericRepository(SchoolContext context)
{
this.context = context;
this.dbSet = context.Set();
}
Слайд 10

public virtual IEnumerable Get( Expression > filter = null, Func ,

public virtual IEnumerable Get( Expression> filter = null, Func,

IOrderedQueryable> orderBy = null,
string includeProperties = "")
{
IQueryable query = dbSet;
if (filter != null)
{
query = query.Where(filter);
}
foreach (var includeProperty in includeProperties.Split
(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
{
query = query.Include(includeProperty);
}
if (orderBy != null)
{
return orderBy(query).ToList();
}
else
{
return query.ToList();
}
}

IEnumerable Get(…)

Слайд 11

public virtual TEntity GetByID(object id) { return dbSet.Find(id); } public virtual

public virtual TEntity GetByID(object id)
{
return dbSet.Find(id);
}
public

virtual void Insert(TEntity entity)
{
dbSet.Add(entity);
}
public virtual void Delete(object id)
{
TEntity entityToDelete = dbSet.Find(id);
Delete(entityToDelete);
}
public virtual void Delete(TEntity entityToDelete)
{
if (context.Entry(entityToDelete).State == EntityState.Detached)
{
dbSet.Attach(entityToDelete);
}
dbSet.Remove(entityToDelete);
}

Імплементація CRUD методів

Слайд 12

public virtual void Update(TEntity entityToUpdate) { dbSet.Attach(entityToUpdate); context.Entry(entityToUpdate).State = EntityState.Modified; } Імплементація CRUD методів

public virtual void Update(TEntity entityToUpdate)
{
dbSet.Attach(entityToUpdate);
context.Entry(entityToUpdate).State =

EntityState.Modified;
}

Імплементація CRUD методів

Слайд 13

Unit of Work (UoW) Патерни об’єктно-реляційної поведінки: • Unit of Work

Unit of Work (UoW)

Патерни об’єктно-реляційної поведінки:
• Unit of Work
• Identity Map

Lazy Load
UnitOfWork покликаний відслідковувати всі зміни даних, які ми здійснюємо з доменною моделлю в рамках бізнес-транзакції. Після того, як бізнес-транзакція закривається, всі зміни потрапляють в БД у вигляді єдиної транзакції.
Слайд 14

Слайд 15

Слайд 16

A possible project structure

A possible project structure

Слайд 17

IUnitOfWork interface public interface IUnitOfWork { GenericRepository DepartmentRepository {get;} GenericRepository CourseRepository

IUnitOfWork interface

public interface IUnitOfWork
{
GenericRepository DepartmentRepository {get;}
GenericRepository CourseRepository

{get;}
GenericRepository PersonRepository{get;}
GenericRepository StudentRepository{get;}
GenericRepository InstructorRepository{get;}
}
Слайд 18

UnitofWork.cs public class UnitOfWork : IUnitOfWork, IDisposable { private SchoolContext context

UnitofWork.cs

public class UnitOfWork : IUnitOfWork, IDisposable
{
private SchoolContext

context = new SchoolContext();
private GenericRepository departmentRepository;
private GenericRepository courseRepository;
private GenericRepository personRepository;
private GenericRepository studentRepository;
private GenericRepository instructorRepository;
//Generic repository instantiation for every entity-set in domain // using a single shared DbContext object within a UoW wrapper
//…
}
Слайд 19

GenericRepository Getters public GenericRepository DepartmentRepository { get { if (this.departmentRepository ==

GenericRepository Getters

public GenericRepository DepartmentRepository
{
get
{


if (this.departmentRepository == null)
{
this.departmentRepository = new GenericRepository(context);
}
return departmentRepository;
}
}
public GenericRepository CourseRepository
{
get
{
if (this.courseRepository == null)
{
this.courseRepository = new GenericRepository(context);
}
return courseRepository;
}
}
Слайд 20

Persist DbContext changes and clean up resources public void Save() {

Persist DbContext changes and clean up resources

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);
}

Слайд 21

How does the architectural wiring come live in the controller ?

How does the architectural wiring come live in the controller ?

public class

CourseController
{
private UnitOfWork unitOfWork = new UnitOfWork();
public ViewResult Index()
{
var courses = unitOfWork.CourseRepository.Get(includeProperties: "Department");
return View(courses.ToList());
}
public ViewResult Details(int id)
{
Course course = unitOfWork.CourseRepository.GetByID(id);
return View(course);
}
//…
}
}
Слайд 22

Sample Edit, Get(…) calls public ActionResult Edit( [Bind(Include = "CourseID,Title,Credits,DepartmentID")] Course

Sample Edit, Get(…) calls


public ActionResult Edit( [Bind(Include = "CourseID,Title,Credits,DepartmentID")] Course

course)
{
try
{
if (ModelState.IsValid)
{
unitOfWork.CourseRepository.Update(course);
unitOfWork.Save();
return RedirectToAction("Index");
}
}
catch (DataException dex)
{
ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists, see your system administrator.");
}
PopulateDepartmentsDropDownList(course.DepartmentID);
return View(course);
}
Слайд 23

private void PopulateDepartmentsDropDownList(object selectedDepartment = null) { var departmentsQuery = unitOfWork.DepartmentRepository.Get(

private void PopulateDepartmentsDropDownList(object selectedDepartment = null)
{
var departmentsQuery =

unitOfWork.DepartmentRepository.Get( orderBy: q => q.OrderBy(d => d.Name));
ViewBag.DepartmentID = new SelectList(departmentsQuery, "DepartmentID", "Name", selectedDepartment);
}
Слайд 24

References http://www.asp.net/mvc/overview/older-versions/getting-started-with-ef-5-using-mvc-4/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application http://www.asp.net/mvc/overview/getting-started/getting-started-with-ef-using-mvc/advanced-entity-framework-scenarios-for-an-mvc-web-application#repo

References
http://www.asp.net/mvc/overview/older-versions/getting-started-with-ef-5-using-mvc-4/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application
http://www.asp.net/mvc/overview/getting-started/getting-started-with-ef-using-mvc/advanced-entity-framework-scenarios-for-an-mvc-web-application#repo