Bit of Technology

  • Archive
  • About Me
    • Advertise
    • Disclaimer
  • Speaking
  • Contact

Building ASP.Net Web API RESTful Service – Part 2

November 25, 2013 By Taiseer Joudeh 18 Comments

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:

  • ASP.NET Web API 2 Attribute Routing.
  • IHttpActionResult as new response type and CORS Support.

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:

C#
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
public interface ILearningRepository
    {
        IQueryable<Subject> GetAllSubjects();
        Subject GetSubject(int subjectId);
 
        IQueryable<Course> GetCoursesBySubject(int subjectId);
 
        IQueryable<Course> GetAllCourses();
        Course GetCourse(int courseId, bool includeEnrollments = true);
        bool CourseExists(int courseId);
 
        IQueryable<Student> GetAllStudentsWithEnrollments();
        IQueryable<Student> GetAllStudentsSummary();
 
        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);
 
        bool SaveAll();
    }

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.

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class LearningRepository : ILearningRepository
    {
        private LearningContext _ctx;
        public LearningRepository(LearningContext ctx)
        {
            _ctx = ctx;
        }
 
        public IQueryable<Subject> GetAllSubjects()
        {
            return _ctx.Subjects.AsQueryable();
        }
 
        /*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.

Source code is available on GitHub.

Related Posts

  • Integrate Azure AD B2C with ASP.NET MVC Web App – Part 3
  • Secure ASP.NET Web API 2 using Azure AD B2C – Part 2
  • Azure Active Directory B2C Overview and Policies Management – Part 1
  • ASP.NET Identity 2.1 Accounts Confirmation, and Password Policy Configuration – Part 2
  • ASP.NET Identity 2.1 with ASP.NET Web API 2.2 (Accounts Management) – Part 1

Filed Under: ASP.NET, ASP.Net Web API, Dependency Injection, Entity Framework, Ninject, Web API Tutorial Tagged With: API, ASP.NET, Code First, Dependency Injection, Entity Framework, Ninject, REST, RESTful, Tutorial, Web API, Web Service

Comments

  1. F Abtin says

    December 26, 2013 at 3:15 am

    Thanks for the great post. How can I use this if my database already exists?!

    Reply
    • tjoudeh says

      December 26, 2013 at 6:28 pm

      Hello F Abtin,

      Can you elaborate more? Didn’t get your question.

      Reply
      • F Abtin says

        December 27, 2013 at 7:24 pm

        I need to build a resful api for an already existing crm, where every object is a new table in the database and there is no fix schema for the database(tables are being created and removed if not required anymore by the user). The crm is being used via a wcf api using session and server cache. I am facing few problems: No fix design for the database. user Session being used which is not restful and its very hard to ignore the layer as it is highly connected with server cache and my datalayer. Thanks for being helpful

        Reply
  2. Franklin says

    February 28, 2014 at 6:55 pm

    I believe the LearningRepository should implement IDisposable and dispose of the LearningContext. Any controllers that use the repository would have to dispose of it as well. This would prevent database connections from waiting to be garbage collected and disconnected.

    Reply
    • Taiseer Joudeh says

      March 4, 2014 at 1:26 pm

      Hello Franklin,
      You are right if I’m not using Ninject, you can’t dispose DBContext manually because it is injected using Ninject, I’m keeping the DBContext alive for each request scope, you can read more about Ninject Object scopes here.

      Reply
  3. Shaina says

    March 21, 2014 at 9:57 am

    Hi

    This is great and it works all on my project. I have a question, though.

    I’d try to delete the tables and run again the project. I’m expecting that it will recreate the tables and insert again the data procided by the seed(). However, it shows an error that the tables aren’t existing.

    After that I deleted the whole DB, run the project and expect the whole thing again. This time it works.

    As far as I know we map only the entities and its properties which is equivalent to the tables and its properties as well.
    But why it doesn’t fixed on its own and the DB which I don’t know where it has been configured are recreated?

    Thanks.

    Reply
    • Shaina says

      March 21, 2014 at 9:58 am

      Sorry I know this was supposed to be in Part 1 🙂

      Reply
    • Taiseer Joudeh says

      March 22, 2014 at 12:12 am

      Hello Shaina,

      I believe that the initialization strategy I’m using will not create tables if they are deleted manually, try to use “DropCreateDatabaseifModelChanges” strategy. Usually when I use CF I do not delete tables manually from database, I delete certain columns and then they get recreated correctly. Never tried to delete the entire table before.

      Reply
  4. goobering says

    April 25, 2014 at 12:40 pm

    Hi Taiseer

    Your tutorial has been seriously helpful in explaining some of these patterns. Now that I’m beginning to implement the concepts in my own work I’m encountering a few issues.

    My implementation of the repository pattern involves developing separate interfaces for each of my domain model entities. Using a single large interface class (such as the ILearningRepository in your example) is going to result in an unmanageably large class. Unfortunately, using a large number of smaller interface classes results in something of a breakdown when I come to the subsequent stages in your tutorial, such as the Parse methods in the ModelFactory. It looks like I’m going to have to write separate overloaded constructors for the ModelFactory to meet the criteria for each of the separate Parse methods:

    //As written in your GitHub example:
    private ILearningRepository _repo;
    public ModelFactory(HttpRequestMessage request, ILearningRepository repo) {}
    //end GitHub example

    //As required by my implementation:
    private IAlphaRepository _alphaRepo;
    private IBetaRepository _betaRepo;
    private ICharlieRepository _charlieRepo;
    private IDeltaRepository _deltaRepo;

    public ModelFactory(HttpRequestMessage request, IAlphaRepository repo) {}
    public ModelFactory(HttpRequestMessage request, IBravoRepository repo) {}
    public ModelFactory(HttpRequestMessage request, ICharlieRepository repo) {}
    public ModelFactory(HttpRequestMessage request, IDeltaRepository repo) {}
    //end my implementation

    I feel like I’m missing something fundamental here. Is it possible to use many smaller interfaces with the factory pattern as you’ve described it in your article?

    Many thanks
    Dale

    Reply
    • Taiseer Joudeh says

      April 29, 2014 at 5:17 pm

      Hi Dale,

      Sorry for the late reply, well if I were you I will consider three options, first one is what you suggested, overloading the ModelFactory Class, second one is creating dedicated ModelFactory class for each Repo, i.e ModelFactoryForAlpha, and the third one you can consider using AutoMapper if you do not want to manipulate your data before presenting them to API consumers. I prefer the second option and maintain smaller ModelFactory classes.

      Hope this help and if you find better solution let me know please 🙂

      Reply
  5. Manos Kanelos says

    May 13, 2014 at 5:37 pm

    Thank you for the very good tutorial! I have a question!
    Is it right to use the ModelFactory inside of Repository? Because in Repository i need to parse PocoModel classes to POCO

    Reply
    • Taiseer Joudeh says

      May 13, 2014 at 5:44 pm

      Hello Manos, glad you liked the article.
      From design pattern perspective it is not recommended to use Model Factory pattern in the Repository Class, you should always try to have single class responsibility. But if your case is complicated then you can do this.
      Hope this answers your question.

      Reply
      • Manos Kanelos says

        May 14, 2014 at 12:17 pm

        Taiseer thank you for your answer.

        If i understand correctly the use of Repository Class is to communicate with entity model (query, insert ,save).May i include some business rule in Repository Class
        In my case before save to database i need to call some web services, get the results in List (T custom POCOModel) and then call save (here is the need of Model Factory to parser POCOModel to POCO).

        Thank you again!! Ι appreciate your help

        Reply
        • Manos Kanelos says

          May 14, 2014 at 2:02 pm

          And please another question.
          Why do not declate a private variable for LearningContext in Controller(eg Course) and use it in functions(GET, POST….) against of use the Ninject library?

          Thank you!

          Reply
          • Taiseer Joudeh says

            May 14, 2014 at 10:51 pm

            Hello Manos
            If you declared private variable for LearningContext inside each controller then for every request we’ll instantiate this object and read connection string from configuration file which is expensive operation.
            If you opened file NinjectWebCommon.cs and looked at method RegisterServices() you will notice that I’m using Ninject to create a single instance of LearningContext for each request handled by the API, this will boost be more efficient that creating private variable, you can read more about Ninject object scopes here: https://github.com/ninject/ninject/wiki/Object-Scopes
            Hope this answers your question.

        • Taiseer Joudeh says

          May 14, 2014 at 10:53 pm

          Hello Manos,
          I recommend to have separate class/layer to do your business validations before calling the repository class, it always better to keep the repository calls clean and do single responsibility which is talking to your database.

          Reply
          • Manos Kanelos says

            May 15, 2014 at 1:59 am

            Taiseer thank you for you answer. Ι appreciate a lot your help!
            I cant understand about the private variable in LearningContext!
            You said that ” for every request we’ll instantiate this object and read connection string from configuration file which is expensive operation”
            But the Ninject for every request create LearningContext and pass it to repository!!! Where is the difference?

            Thank you!

  6. Mohamed Mostafa says

    November 17, 2017 at 2:49 pm

    Thanks a lot for your incredible tutorials but I have a small comment, I see no use of using the AsQueryable() method on a DbSet collection that already implements the IQueryable interface since the compiler decides whether to generate code for a delegate or an expression tree from a lambda expression based on the type of the collection and if it is implicitly convertible to the IQueryable interface the compiler will generate an expression tree, so I hope you’d explain that bit, thanks.

    Reply

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

About Taiseer

Husband, Father, Consultant @ MSFT, Life Time Learner... Read More…

Buy me a coffeeBuy me a coffee

Recent Posts

  • Integrate Azure AD B2C with ASP.NET MVC Web App – Part 3
  • Secure ASP.NET Web API 2 using Azure AD B2C – Part 2
  • Azure Active Directory B2C Overview and Policies Management – Part 1
  • ASP.NET Web API Claims Authorization with ASP.NET Identity 2.1 – Part 5
  • ASP.NET Identity 2.1 Roles Based Authorization with ASP.NET Web API – Part 4

Blog Archives

Recent Posts

  • Integrate Azure AD B2C with ASP.NET MVC Web App – Part 3
  • Secure ASP.NET Web API 2 using Azure AD B2C – Part 2
  • Azure Active Directory B2C Overview and Policies Management – Part 1
  • ASP.NET Web API Claims Authorization with ASP.NET Identity 2.1 – Part 5
  • ASP.NET Identity 2.1 Roles Based Authorization with ASP.NET Web API – Part 4

Tags

AJAX AngularJS API API Versioning ASP.NET ASP.Net 5 Authentication Autherization Server Azure Active Directory Azure Active Directory B2C Azure AD B2C basic authentication Code First Dependency Injection Documentation Entity Framework Entity Framework 7 Facebook Foursquare API Google Authenticator Identity jQuery JSON JSON Web Tokens JWT MVC 6 Ninject OAuth OData Resource Server REST RESTful RESTful. Web API Single Page Applications SPA Swagger-ui Swashbuckle TFA Token Authentication Tutorial Two Factor Authentication Web API Web API 2 Web API Security Web Service

Search

Copyright © 2022 · eleven40 Pro Theme on Genesis Framework · WordPress · Log in