Skip to content
  • iImagine
  • Register
  • Log In

Web Development School

Learning made easy.

  • Books
    • Beginning Web Development with ASP.Net Core & Client-Side Technologies
      • TOC
      • Part 1
        • Chapter 1: Static HTML – Designing the landing page
      • Part 2
        • Chapter 2: ASP.Net Core – Let’s talk Dynamic
        • Chapter 3: Introduction to ASP.Net Core MVC
          [ASP.Net Core v9]
      • Part 4
        • Chapter 7: Using Server Side & Client Side technologies together
          [ASP.Net Core v7 & Angular 15]
  • Environment Setup
    • Installing Angular
    • Installing Visual Studio 2022
    • Installing SQL Server 2022 Express
    • Installing Postman
    • Installing Git for Windows
  • Blog
  • iImagine WebSolutions
  • Events
  • Learning Videos
  • Toggle search form

Repository Pattern: VehicleRepository

In this module we are going to implement the repository pattern in the Vehicles controller. This will help us solve the problem in unit testing the controller we ran into in the last module.

We are going to create a dependency on the Vehicles Repository in the Vehicles controller so that we can isolate that component during testing of the controller HTTP GET method.

Note: The pathway I am using for development in this module is: C:\Development\FredsCars\FullStack\Module25.
Table Of Contents
  1. Create the Vehicle Repository
    • Create the Vehicle Repository Interface
    • Create the Vehicle Repository Class
  2. Register the Vehicle Repository with DI
  3. Use the IVehicle Repository in the Vehicle Controller
  4. What's Next

Create the Vehicle Repository

As noted in the last module, one of the keys to isolating a component in C# is through interfaces. We are going to use an interface to define what the repository should look like. What properties it should have, what functions it should perform, and so on. You can think of this as an API to the repository component we are about to build.

Create the Vehicle Repository Interface

Create a new folder on the root of the FredsCarsAPI project and in the new folder create a file called IVehicleRepository. Fill the new file with the following contents.

FredsCarsAPI/Repositories/IVehicleRepository.cs

using FredsCarsAPI.Models;

namespace FredsCarsAPI.Repositories
{
    public interface IVehicleRepository
    {
        IQueryable<Vehicle> Vehicles { get; }
    }
}

In the code above we have defined an interface called IVehicleRespository. This interface defines a read only property called Vehicles that returns an IQueryable<Vehicle>. This is saying that any class that implements me must have this property and implement it’s get accessor function.

One of the advantages to using an interface, is that the client code doesn’t need to know the implementation details of the component. Further more, we can replace the concrete implementations of the interface anytime we need a different behavior. This is going to come in handy when we get to the controller unit test as we will soon see.

Create the Vehicle Repository Class

In the Repositories folder, create a new class file called VehicleRepository.cs and fill it with the contents below.

FredsCarsAPI/Repositories/VehicleRepository.cs

using FredsCarsAPI.Data;
using FredsCarsAPI.Models;

namespace FredsCarsAPI.Repositories
{
    public class VehicleRepository : IVehicleRepository
    {
        private ApplicationDbContext _context;

        public VehicleRepository(ApplicationDbContext context)
        {
            _context = context;
        }

        public IQueryable<Vehicle> Vehicles => _context.Vehicles;
    }
}

In the code above we have created a new class called VehicleRepository that implements the IVehicleRepository interface. This class will be the concrete implimentation of the interface in the application during runtime. The colon after the class name can be read as implements in this case. (This operator is also used to inherit from another class but here it is being used to implement an interface.)

public class VehicleRepository : IVehicleRepository

Next we create a private variable called _context of type ApplicationDbContext. We receive the ApplicationDbContext in the constructor through DI and set the private _context variable to the incoming context. We registered our DbContext with DI back in module 22.

At this point we have all of the plumbing we need in the Vehicle Repo class. Now we can actually implement the Repo interface with the next single simple line.

public IQueryable<Vehicle> Vehicles => _context.Vehicles;

This line declares the mandatory interface variable Vehicles of type IQueryable<Vehicle> and returns the Vehicles DbSet of the DbContext using the “goes into” operator (‘=>’).

Register the Vehicle Repository with DI

The next thing we need to do is register the repository with dependency injection. Open the program.cs file and make the modification shown below in bold blue font.

FredsCarsAPI/Program.cs

/*** existing code ***/

// Add services to the container.
builder.Services.AddDbContext<ApplicationDbContext>(options =>
    options.UseSqlServer(
        builder.Configuration
        .GetConnectionString("ApplicationContext")));

builder.Services.AddScoped<IVehicleRepository, VehicleRepository>();

/*** existing code ***/

The code above adds the Vehicle Repository to the DI services container using the AddScoped lifetime for the service. This means the lifetime of the repo will only be for one Web API request. And a new instance will be created for each request.

Now anytime a component asks for an instance of an IVehicleRepository service in its constructor parameter list, ASP.Net Core DI will create an instance of that service and feed it to the constructor.

Use the IVehicle Repository in the Vehicle Controller

Open the VehiclesController.cs file and make the modifications below in bold blue font.

FredsCarsAPI/Controllers/VehiclesController.cs

using FredsCarsAPI.Data;
using FredsCarsAPI.Models;
using FredsCarsAPI.Models.DTOs;
using FredsCarsAPI.Repositories;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;

namespace FredsCarsAPI.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class VehiclesController : ControllerBase
    {
        private IVehicleRepository _vehicleRepo;

        public VehiclesController(IVehicleRepository vehicleRepo)
        {
            _vehicleRepo = vehicleRepo;
        }

        [HttpGet]
        public async Task<ApiResult<VehicleDTO>> GetVehicles(
            int pageIndex = 0, int pageSize = 10)
        {
            // get Vehicles page
            var dataQuery = _vehicleRepo.Vehicles.AsNoTracking()
                .Include(v => v.VehicleType)
                .ConvertVehiclesToDTOs();

            return await ApiResult<VehicleDTO>.CreatAsync(
                dataQuery,
                pageIndex,
                pageSize);
        }
    }
}

In the code above, we have modified our DI setup to take in the Vehicle Repo rather then the whole DbContext.
From this:

private ApplicationDbContext _context;

        public VehiclesController(ApplicationDbContext context)
        {
            _context = context;
        }

to this:

private IVehicleRepository _vehicleRepo;

public VehiclesController(IVehicleRepository vehicleRepo)
{
    _vehicleRepo = vehicleRepo;
}

The fact that vehicleRepo is an interface means that it hides its implementation details from the Vehicle controller. And the Vehicle controller doesn’t care what those details are or where they come from. We have already registered the concrete implementation with DI for runtime in program.cs. And we will be able to use a different implementation for unit testing as we’ll see in the next module.

Within the actual HTTP GET method, we just made one very little change.

// get Vehicles page
var dataQuery = _vehicleRepo.Vehicles.AsNoTracking()
    .Include(v => v.VehicleType)
    .ConvertVehiclesToDTOs();

We are now using the repo to offload the duties of hitting the DbContext from the controller.


If you run the program at this point the behavior should be the same. And if you run some API tests from Swagger or Postman, the JSON result should also be the same as in previous modules.

What’s Next

Now that we’ve completed our little pitstop, learned about the repository pattern, and refactored our controller to use it, we can move along and in the next module finish our unit testing for the VehiclesController.

< Prev
Next >

Leave a ReplyCancel reply

Chapter 1: Static HTML – Designing the landing page.

  • Static HTML – Designing the landing page.
  • Let’s get started!
  • Mock your site with HTML
  • Make CSS easy with Bootstrap
  • Mock your content
  • Introducing JavaScript
  • JavaScript Code Improvements
  • Results Data
  • Images and the HTML Image Element.
  • Revisiting Reusability for CSS and JavaScript
  • Reuse for HTML: PART 1
  • Reuse for HTML: PART 2
  • Details Page – Using a Bootstrap Component
  • Creating Links
  • Chapter One Conclusion

Chapter 2: ASP.Net Core – Let’s talk Dynamic

  • Introduction to ASP.Net Core
  • What is .Net?
  • What is ASP.Net
  • Introduction to Entity Framework Core

Chapter 3: ASP.Net MVC Core – Models, Views, and Controllers [ASP.Net Core v9]

  • Introduction to ASP.Net Core MVC
  • Create the project: ASP.Net Core MVC
  • Explore the ASP.Net Core Empty Web Project Template
  • Configure the Application for MVC
  • Create a Controller: Home Controller
  • Create a View: Index View for the Home Controller
  • Install Bootstrap using Libman
  • Create the Layout template
  • Create the Model
  • Install EF Core & Create the Database
  • Seed the Database: Loading test data
  • DI (Dependency Injection): Display a List of Vehicles
  • Repository Pattern: The Vehicles Repo
  • Unit Test 1: Home Controller Can Use Vehicle Repository
  • Unit Test 2: Vehicle Repository Can Return List
  • Add the ImagePath Migration and Thumbnail images to results
  • Pagination: Create a Custom Tag Helper
  • Sorting
  • Category Filter
  • Partial View: Break out the vehicle results
  • View Component: Create dynamic category buttons
  • Create the Details page
  • Create the Create Page

Chapter 7: Using Server Side & Client Side technologies together. [ASP.Net Core v7 & Angular v15]

  • Intro to Full Stack Development
  • Fred’s Cars – Full Stack Development
  • Prepare the environment
  • Create the Visual Studio Solution
  • Add the ASP.Net Core Web API project
  • Add the Angular Project
  • Wire it up!
  • WeatherForecast: Understanding the basics
  • Vehicles API Controller: Mock Data
  • Vehicles Angular Component: Consuming Data
  • Routing and Navigation
  • Using a Component Library: Angular Material
  • Our first Angular Material Component: MatToolbar
  • Configuring for Saas: CSS with superpowers
  • Create the Header & Footer components
  • Displaying Results with MatTable
  • Loading: Using a Progress Spinner
  • MatTable: Client-Side Paging and Sorting
  • MatSidenav: Create a Search Sidebar
  • MatCheckbox: Category Search UI
  • Adding an image to the welcome page
  • Create the database with Entity Framework Core migrations
  • MatPaginator & PageEvent: Custom Server-Side Paging
  • Unit Testing: Custom Server-Side Paging
  • Repository Pattern: VehicleRepository
  • Unit Test: Paging in the Vehicles controller
  • Server-Side Sorting
  • Unit Tests: Sorting
  • Filter (Quick Search)
  • Unit Tests: Filter feature
  • Advanced Search: Categories
  • Unit Tests: Search by category
  • Progress Spinner: Final Fix

TOC

  • What were WebForms?
  • Enter MVC
    • Understanding MVC
    • Advantages of MVC
  • ASP.Net Core MVC – A total rewrite
  • ASP.Net Core 2 MVC – Here come Razor Pages
    • Understanding Razor Pages
  • ASP.Net Core 3 – Dropping the MVC reference
    • Understanding Blazor
  • Dropping the MVC reference
  • Hello .Net 5!
  • What’s Next? – Here comes .Net 6.

Recent Posts

  • Angular Commands Cheat Sheet
  • Installing Git for Windows
  • Installing Postman
  • Installing SQL Server 2022 Express
  • Installing Visual Studio 2022

Recent Comments

No comments to show.

Archives

  • November 2023
  • October 2023
  • June 2023
  • October 2021

Categories

  • Angular
  • ASP.Net
  • Environment Setup
  • See All
  • SQL Server
  • Visual Studio
  • Web API & Rest Services

WordPress Theme Editor

Copyright © 2025 Web Development School.

Powered by PressBook Blog WordPress theme