This is the second part of Building ASP.Net Web API RESTful Service Series. The topics we’ll cover are:
- Building the Database Model using Entity Framework Code First – Part 1.
- Applying the Repository Pattern for the Data Access Layer – Part 2 (This Post).
- Getting started with ASP.Net Web API – Part 3.
- Implement Model Factory, Dependency Injection and Configuring Formatters – Part 4.
- Implement HTTP actions POST, PUT, and DELETE In Web API – Part 5.
- Implement Resources Association – Part 6.
- Implement Resources Pagination – Part 7.
- Securing Web API – Part 8.
- Preparing Web API for Versioning – Part 9.
- Different techniques to Implement Versioning – Part 10.
- Caching resources using CacheCow and ETag – Part 11.
Update (2014-March-5) Two new posts which cover ASP.Net Web API 2 new features:
Applying the Repository Pattern for the Data Access Layer
Applying Repository Pattern is useful to isolate domain objects from the details of database access layer. It will act as an abstraction layer over the mapping layer where query constructions and database objects manipulation take place. As well the Repository will act like in-memory domain object collection where objects can be added or removed from the Repository as they are removed from a simple collection of objects, moreover the Repository will be responsible to execute the appropriate operations behind the scenes.
Before we dig into the Repository implementation let’s list the use cases needed to be implemented in our Web API, this for sure will help us in building the right Repository methods and operations:
- Listing all available subjects, and listing single subject by querying ID.
- Listing all available courses including the sub-models (Subject, and Tutor).
- Getting single course by querying ID including the sub-models(Subject, Tutor, and Enrolled Students)
- Listing all available students including all sub-models (Enrolled in Courses, Course Subject, and Tutor)
- Get summary of all available students.
- List all enrolled students in specific course by querying course ID.
- List all classes for a certain student by querying Username.
- Get certain student by querying Username.
- Authenticate students by validating Username and Password.
- Enroll an authenticated student in a course.
- CRUD operations for Students.
- CRUD operations for Courses.
Building the Repository Pattern
We need to add new Interface named “ILearningRepository” to implement all the use cases listed above:
public interface ILearningRepository
Subject GetSubject(int subjectId);
IQueryable<Course> GetCoursesBySubject(int subjectId);
Course GetCourse(int courseId, bool includeEnrollments = true);
bool CourseExists(int courseId);
IQueryable<Student> GetEnrolledStudentsInCourse(int courseId);
Student GetStudentEnrollments(string userName);
Student GetStudent(string userName);
Tutor GetTutor(int tutorId);
bool LoginStudent(string userName, string password);
bool Insert(Student student);
bool Update(Student originalStudent, Student updatedStudent);
bool DeleteStudent(int id);
int EnrollStudentInCourse(int studentId, int courseId, Enrollment enrollment);
bool Insert(Course course);
bool Update(Course originalCourse, Course updatedCourse);
bool DeleteCourse(int id);
The methods in the interface above covers all the operations needed in our Web API, note how we are returning IQueryable<T> for any method returns a collection of objects, this will facilitate the pagination, sorting, and results ordering in our Web API because IQueryable will give us deferred execution and fully support for LINQ-to-SQL. In other words IQueryable result will save us from returning too many unwanted rows from the database.
Now we need to add new class called “LearningRepository” which will implement the interface “ILearningRepository”. I’ll list partial implementation of the class here. We’ll be able to see the full implementation by browsing the code on GitHub or by downloading the source.
public class LearningRepository : ILearningRepository
private LearningContext _ctx;
public LearningRepository(LearningContext ctx)
_ctx = ctx;
public IQueryable<Subject> GetAllSubjects()
/*Rest of methods implementation goes here....*/
You can notice that the constructor of the class “LearningRepository” accepts the database context object “LearningContext” and there is a private member “_ctx” which is used to interact with all DbSet objects without instantiating it. That design pattern is called Dependency Injection, in simple words it means that objects do not create other objects on which they rely to do their work. Instead, they get the objects that they need from an outside source.
So in our situation the class “LearningRepository” depends on class “LearningContext”, but it won’t create an instance from it to complete its work, instead we will inject this object to it using an external DI framework called Ninject. We’ll cover this deeply in the coming parts. If you are new to Dependency Injection design pattern, I recommend you to read my previous blog post about it.
Until this point our data access layer is complete and ready to be used with our Web API, so lets jump to the next post where we’ll start working on Web API.