Phần 1: Ví dụ Repository Pattern trong C# - Design Pattern: Data Access Layer Patterns
1. Giới thiệu chung
Trong bài viết này, mình sẽ giới thiệu và đưa ra ví dụ một trong những design pattern phổ biến có tên là Repository Pattern. Đây là giải pháp được sử dụng khá phổ biến trong nhiều dự án, hiểu nôm na là chúng ta sẽ tạo thêm 1 lớp để tránh việc phụ thuộc của tầng xử lý với tầng truy xuất dữ liệu từ database.
2. Vấn đề
Trong các dự án đơn thuần, chúng ta có thể chia ứng dụng thành 3 tầng cơ bản bao gồm Controller, Data Access và Database. Kiểu thiết kế này bộc lộ điểm yếu trong việc phát triển và testing sau này bởi tầng Controller bị phụ thuộc vào tầng Data Access (Hình minh họa)
3. Thiết kế
Đầu tiên mình có 1 dự án có 3 tầng như sau (hình minh họa). Trong đó tầng Web sẽ chứa Model Views và Controllers, tầng Infrastructure sẽ chứa các truy vấn dữ liệu cũng như các services và tầng Domain sẽ là nơi chứa toàn bộ domain (Entitites) của dự án.
Nhìn vào hàm Create trong OrderControllers ở tầng Controllers. Có thể thấy rõ rằng việc truy cập dữ liệu được thực hiện ngay trong file OrderController. Một cách đơn giản là hiện tại OrderController tạo ra một biến dbContext và thực hiện các hàm truy xuất dữ liệu ngay trong chính nó.
Điều này bạn nên tránh né vì nó gây ra sự phụ thuộc giữ tầng Controller và tầng Data, giả sử bạn muốn thử xem test xem hàm này có chạy được không thì nếu áp dụng phương pháp này thì trong database cũng sẽ bị thêm 1 dòng dư thừa này đúng không ?. Để tránh điều này xảy ra mình sẽ áp dụng Repository Pattern.
Đầu tiên mình cần tạo thêm 2 lớp: lớp Repository và interface của nó IRepository. Trong lớp IRepository sẽ là nơi bạn khởi tạo các hàm truy xuất dữ liệu CRUD (Create, Read, Update, Delete)
Những câu lệnh truy vấn trong ví dụ là các hàm trong Entity Framework, trong nội dụng bài viết này mình sẽ không đề cập về nó nhưng chúng ta chỉ cần hiểu việc chúng ta làm là dịch bước xử lí ở trong Controller ban đầu về lớp Data Access. Điều đó đồng nghĩa với việc lớp Controller không biết gì về cách chúng ta truy xuất dữ liệu, nếu sau này chúng ta có muốn thay đổi hay chỉnh sửa gì về cách truy xuất thì Controller cũng không bị ảnh hưởng.
Nhìn một lần nữa vào OrderController chúng ta sẽ sử dụng kĩ thuật Dependency Injection để có thể sử các Repository đã tạo ở phần trên vào bên trong Controller này
Vậy là các lớp Controller đã được độc lập với lớp Data Access rồi. Trong phần này mình đã giới thiểu tổng quan và đưa ra ví dụ cơ bản về cách Repository pattern áp dụng cho các dự án .NET nói riêng, bạn có áp dụng tương tự cho mọi úng dụng bạn muốn. Trong phần tiếp theo mình sẽ nói về Unit of Work Patter...