Khoanglang89
Bạn hãy đăng nhập hoặc đăng ký
Khoanglang89

NHẬN THIẾT KẾ WEBSITE/ SOFTWARE - LÀM ĐỒ ÁN TỐT NGHIỆP, ĐỒ ÁN CHUYÊN MÔN NGÀNH CÔNG NGHỆ THÔNG TIN


You are not connected. Please login or register

Xem chủ đề cũ hơn Xem chủ đề mới hơn Go down  Thông điệp [Trang 1 trong tổng số 1 trang]

Admin

avatar

Admin
Admin
Loading
Repository Pattern là gì?
Repository Pattern  là một lớp trừu trượng (abstraction ) giữa tầng Data access và tầng Business logic của một ứng dụng. Đây là một mô hình truy cập dữ liệu chặt chẽ hơn, bảo mật hơn cũng như gọn gàng hơn. Chúng ta sẽ tạo ra một logic truy cập dữ liệu trong một lớp riêng biệt, hoặc một tập hợp các lớp gọi là Repository, với nhiệm vụ là kết nối với tầng Business Model của ứng dụng

Nó cho phép tất cả các code của bạn có thể truy cập và sử dụng các đối tượng mà không cần quan tâm đến đối tượng đó tồn tại như thế nào. Tất cả các thông tin được lưu lại, bao gồm cả các mapping từ table tới các object đều được lưu trữ an toàn trong Repository.
Thông thường, chúng ta sẽ tìm thấy các truy vấn SQL hay Linq nằm rải rác trong các code và khi bạn muốn thực hiện một thao tác với database thì bạn sẽ phải tìm trong code cũng như tìm các thuộc tính của bảng để xử lý. Điều này gây nên sự lãng phí về thời gian cũng như ảnh hưởng đến code chung.
Với Repository Pattern, bạn chỉ cần thay đổi một đối tượng và một Repository, việc này tiết kiệm khá nhiều công sức cũng như ảnh hưởng rất nhỏ đến code chung.
Một số lý do chúng ta nên sử dụng Repository Pattern:
    - Một nơi duy nhất để thay đổi quyền truy cập dữ liệu cũng như xử lý dữ liệu
    - Một nơi duy nhất chịu trách nhiệm cho việc mapping các bảng vào object.
    - Tăng tính bảo mật và rõ ràng cho code.
    - Rất dễ dàng để thay thế một Repository với một implementation giả cho việc testing, vì vậy bạn không cần chuẩn bị một cơ sở dữ liệu có sẵn... 

Ví dụ chúng ta có một ASP.Net MVC Controller tên là CustomerController, trong đó có các action thực hiện CRUD (Create, Read, Update and Delete) lên database và dùng EF(Entity Framework) để truy cập và xử lý database:

Như hình trên, các action CRUD cũng như các action khác sẽ thao tác trực tiếp nhanh chóng với lớp data context của EF để truy vấn và nhận dữ liệu. Và EF sẽ làm việc trực tiếp với database. Mặc dù ứng dụng trên hoạt động rất tốt nhưng chúng có những nhược điểm như các code thao tác với database đều nhúng trực tiếp trong các action. Điều này gây nên sự trùng lặp và Controller sẽ dễ bị thay đổi khi có một sự thay đổi nhỏ trong truy vấn dữ liệu về mặt logic. Ví dụ, nếu chúng ta có 2 Controller thực hiện đồng thời các thao tác CRUD thì với việc code như trên sẽ tạo ra sự trùng lặp về mã (tất cả đều là CRUD) và khi chỉnh sửa, cũng phải chỉnh sửa ở hai Controller.
Để giải quyết vấn đề này ta dùng Customer Repository, làm trung gian giữa các phần của ứng dụng với tầng dữ liệu. Một Repository chứa tất cả các truy cập cơ sở dữ liệu từ các phần còn lại của ứng dụng. Khi cần có sự thay đổi, nâng cấp thì chỉ thực hiện trên Repository nên các Controller vẫn được vẹn toàn. Điều này cũng rất có lợi cho việc testing khi mà bạn không cần phải có một cơ sở dữ liệu thật sự để có thể test ứng dụng.
Với việc dùng Customer Repository, Controller sẽ không làm việc trực tiếp với EF Data context. Ngoài ra sẽ không có bất kỳ truy vấn dữ liệu nào được viết trong các action, tất cả các hoạt động này đều được Customer Repository đảm nhiệm.

Tạo Model dùng Entity Framework
Tạo mới một ASP.NET MVC web application empty template. Add một ADO.NET Entity Data Model vào thư mục Model từ cơ sở dữ liệu Northwind, chỉ chọn bảng Customer như hình bên dưới

Tạo Customer Repository
Một Repository thường có 5 phương thứ là SelectAll, SelectById, Insert, Update, Delete, có thể thêm bớt các phương thức. Chúng ta sẽ định nghĩa một Interface ICustomerRepository
?
1
2
3
4
5
6
7
8
9
Code:
public

Code:
interface

Code:
ICustomerRepository
Code:
{
  
Code:
IEnumerable SelectAll();
  
Code:
Customer SelectByID(
Code:
string

Code:
id);
  
Code:
void

Code:
Insert(Customer obj);
  
Code:
void

Code:
Update(Customer obj);
  
Code:
void

Code:
Delete(
Code:
string

Code:
id);
  
Code:
void

Code:
Save();
Code:
}
ICustomerRepository interface có 5 phương thức:

  • SelectAll(): Trả về tất cả các dòng trong Customer kiểu Enumerable
  • SelectByID(): Trả về Customer theo id nhận vào.
  • Insert(): Có đối số là một object và Insert vào Customers DbSet.
  • Update(): Có đối số là một object và thực hiện Edit vào Customers DbSet
  • Delete(): Xóa Customer theo id.
  • Save(): Lưu lại các thay đổi trong cơ sở dữ liệu Northwind.

Tiếp theo, tạo một class CustomerRepository kế thừa ICustomerRepository
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
Code:
public

Code:
class

Code:
CustomerRepository:ICustomerRepository
Code:
{
  
Code:
private

Code:
NorthwindEntities db =
Code:
null
Code:
 
  
Code:
public

Code:
CustomerRepository()
  
Code:
{
    
Code:
this
Code:
.db =
Code:
new

Code:
NorthwindEntities();
  
Code:
 
  
Code:
public

Code:
CustomerRepository(NorthwindEntities db)
  
Code:
{
    
Code:
this
Code:
.db = db;
  
Code:
 
  
Code:
public

Code:
IEnumerable SelectAll()
  
Code:
{
    
Code:
return

Code:
db.Customers.ToList();
  
Code:
 
  
Code:
public

Code:
Customer SelectByID(
Code:
string

Code:
id)
  
Code:
{
    
Code:
return

Code:
db.Customers.Find(id);
  
Code:
 
  
Code:
public

Code:
void

Code:
Insert(Customer obj)
  
Code:
{
    
Code:
db.Customers.Add(obj);
  
Code:
 
  
Code:
public

Code:
void

Code:
Update(Customer obj)
  
Code:
{
    
Code:
db.Entry(obj).State = EntityState.Modified;
  
Code:
}
 
  
Code:
public

Code:
void

Code:
Delete(
Code:
string

Code:
id)
  
Code:
{
    
Code:
Customer existing = db.Customers.Find(id);
    
Code:
db.Customers.Remove(existing);
  
Code:
 
  
Code:
public

Code:
void

Code:
Save()
  
Code:
{
    
Code:
db.SaveChanges();
  
Code:
}
Code:
}
Ở đây, chúng ta định nghĩa 2 Contructor, một không có đối số, và một có đối số là một data context (phương thức này được dùng để gọi một data context từ bên ngoài vào khi thực hiện test).

Dùng CustomerRepository trong Controller
Tạo một CustomerController
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
Code:
public

Code:
class

Code:
CustomerController : Controller
Code:
{
  
Code:
private

Code:
ICustomerRepository repository =
Code:
null
Code:
;
 
  
Code:
public

Code:
CustomerController()
  
Code:
{
    
Code:
this
Code:
.repository =
Code:
new

Code:
CustomerRepository();
  
Code:
}
 
  
Code:
public

Code:
CustomerController(ICustomerRepository repository)
  
Code:
{
    
Code:
this
Code:
.repository = repository;
  
Code:
}
 
  
Code:
public

Code:
ActionResult Index()
  
Code:
{
    
Code:
List model = (List)repository.SelectAll();
    
Code:
return

Code:
View(model);
  
Code:
}
 
  
Code:
public

Code:
ActionResult New()
  
Code:
{
    
Code:
return

Code:
View();
  
Code:
}
 
  
Code:
public

Code:
ActionResult Insert(Customer obj)
  
Code:
{
    
Code:
repository.Insert(obj);
    
Code:
repository.Save();
    
Code:
return

Code:
View();
  
Code:
}
 
  
Code:
public

Code:
ActionResult Edit(
Code:
string

Code:
id)
  
Code:
{
    
Code:
Customer existing = repository.SelectByID(id);
    
Code:
return

Code:
View(existing);
  
Code:
}
 
  
Code:
public

Code:
ActionResult Update(Customer obj)
  
Code:
{
    
Code:
repository.Update(obj);
    
Code:
repository.Save();
    
Code:
return

Code:
View();
  
Code:
}
 
  
Code:
public

Code:
ActionResult ConfirmDelete(
Code:
string

Code:
id)
  
Code:
{
    
Code:
Customer existing = repository.SelectByID(id);
    
Code:
return

Code:
View(existing);
  
Code:
}
 
  
Code:
public

Code:
ActionResult Delete(
Code:
string

Code:
id)
  
Code:
{
    
Code:
repository.Delete(id);
    
Code:
repository.Save();
    
Code:
return

Code:
View();
  
Code:
}
Code:
}
Tạo Repository Generic
Các Repository Pattern vừa tạo ở trên hoạt động rất tốt, tuy nhiên chúng cũng có nhược điểm đó là tương ứng với mỗi table trong data context thì chúng ta lại tạo một Repository tương ứng. Điều này không giải quyết được triệt để vấn đề chúng ta nêu ra ở trên và cũng chưa là một Repository Pattern đúng nghĩa.
Để làm được điều này chúng ta xây dựng lớp IGenericRepository interface như sau:
?
1
2
3
4
5
6
7
8
9
Code:
public

Code:
interface

Code:
IGenericRepository where T:
Code:
class
Code:
{
  
Code:
IEnumerable SelectAll();
  
Code:
T SelectByID(
Code:
object

Code:
id);
  
Code:
void

Code:
Insert(T obj);
  
Code:
void

Code:
Update(T obj);
  
Code:
void

Code:
Delete(
Code:
object

Code:
id);
  
Code:
void

Code:
Save();
Code:
}
IGenericRepository interface là một generic interface, định nghĩa một tập các phương thức giống như ICustomerRepository ở trên. Với interface này, Customer trong data context có thể sử dụng T ở bất kỳ vị trí nào. Chúng ta chú ý 2 phương thức SelectByID() và Delete() bây giờ có đối số là một object chứ không phải là string như ở trên vì các table khác nhau có thể có các loại khóa chính có kiểu dữ liệu khác nhau.

Tiếp theo, chúng ta thêm một class tên là GenericRepository kế thừa interface IGenericRepository như sau:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
Code:
public

Code:
class

Code:
GenericRepository:IGenericRepository where T :
Code:
class
Code:
{
  
Code:
private

Code:
NorthwindEntities db =
Code:
null
Code:
;
 
 
  
Code:
private

Code:
DbSet table =
Code:
null
Code:
;
 
  
Code:
public

Code:
GenericRepository()
  
Code:
{
    
Code:
this
Code:
.db =
Code:
new

Code:
NorthwindEntities();
    
Code:
table = db.Set();
  
Code:
}
 
  
Code:
public

Code:
GenericRepository(NorthwindEntities db)
  
Code:
{
    
Code:
this
Code:
.db = db;
    
Code:
table = db.Set();
  
Code:
}
 
  
Code:
public

Code:
IEnumerable SelectAll()
  
Code:
{
    
Code:
return

Code:
table.ToList();
  
Code:
}
 
  
Code:
public

Code:
T SelectByID(
Code:
object

Code:
id)
  
Code:
{
    
Code:
return

Code:
table.Find(id);
  
Code:
}
 
  
Code:
public

Code:
void

Code:
Insert(T obj)
  
Code:
{
    
Code:
table.Add(obj);
  
Code:
}
 
  
Code:
public

Code:
void

Code:
Update(T obj)
  
Code:
{
    
Code:
table.Attach(obj);
    
Code:
db.Entry(obj).State = EntityState.Modified;
  
Code:
}
 
  
Code:
public

Code:
void

Code:
Delete(
Code:
object

Code:
id)
  
Code:
{
    
Code:
T existing = table.Find(id);
    
Code:
table.Remove(existing);
  
Code:
}
 
  
Code:
public

Code:
void

Code:
Save()
  
Code:
{
    
Code:
db.SaveChanges();
  
Code:
}
Code:
}
Đối với class này, bạn không thể generic T để truy cập DbSet giống như là một thuộc tính của data context được, vì thế một biến DbSet được khai báo ở trên cùng trỏ đến một DbSet thích hợp dựa trên loại của generic T.

Dùng GenericRepository trong Controller
Tạo Controller Customer như sau:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Code:
public

Code:
class

Code:
CustomerController : Controller
Code:
{
  
Code:
private

Code:
IGenericRepository repository =
Code:
null
Code:
;
 
  
Code:
public

Code:
CustomerController()
  
Code:
{
    
Code:
this
Code:
.repository =
Code:
new

Code:
GenericRepository();
  
Code:
}
 
  
Code:
public

Code:
CustomerController(IGenericRepository repository)
  
Code:
{
    
Code:
this
Code:
.repository = repository;
  
Code:
}
  
Code:
...
  
Code:
...
Code:
}
Tóm lại
Các Repository Pattern giúp bạn tách biệt các mã thao tác với cơ sở dữ liệu với toàn bộ phần còn lại của hệ thống. Sự tách biệt này giúp cho việc giảm tải mã cho hệ thống khi giảm được sự lặp đi lặp lại các đoạn mã có cùng một mục đích, qua nó giúp việc bảo trì, nâng cấp cho hệ thống được đơn giản và hiệu quả hơn
Codeguru


_________________
Có nỗi buồn triền miên, làm trái tim hoá đá
Có những dòng lệ nhỏ, khiến đá hoá thành tim.

-------------------------------------------------------------------------------------------------------
Program Skills:  ASP.Net MVC 3/4; C#; VB.Net/ VB 6.0; Java Applet/Swing; JS/JavaScript; Bootstrap/ AngularJS; HTML/CSS; Turbo C/ Turbo C++; Pascal...
Xem mẫu Phần mêm quản lý ở đây     -           Xem mẫu Bán hàng trực tuyến ở đây
Nguyễn Ích Hoàn
new_life02081989@yahoo.com
nguyenichhoan1989@gmail.com
Xem lý lịch thành viên http://khoanglang89.forumvi.com

Xem chủ đề cũ hơn Xem chủ đề mới hơn Về Đầu Trang  Thông điệp [Trang 1 trong tổng số 1 trang]

Bài viết mới cùng chuyên mục

      Permissions in this forum:
      Bạn không có quyền trả lời bài viết