top of page

Building Dynamic PWAs in Angular and ASP.NET Core with a Multi-Tenant Project

Progressive Web Apps (PWAs) have revolutionized web development by providing a seamless user experience with offline capabilities and native app-like features. In this article, we will explore how to create a dynamic PWA using Angular and ASP.NET Core, along with implementing multi-tenancy for scalability and security.


What is a Progressive Web App (PWA)?

A Progressive Web App is a web application that leverages modern web technologies to provide users with an immersive, fast, and reliable experience. PWAs can be installed on users' devices, work offline, and utilize features such as push notifications, background sync, and caching.


Angular is a powerful JavaScript framework for building dynamic web applications, offering a component-based architecture and a rich set of tools for front-end development. ASP.NET Core is a cross-platform framework for building high-performance web applications and APIs using C#. It provides a robust backend infrastructure and supports seamless integration with Angular.


What is Multi-Tenancy?

Multi-tenancy refers to an architecture where a single application serves multiple tenants or customers. Each tenant has its own isolated data and configuration, ensuring scalability and security. We will implement multi-tenancy in our project to demonstrate its benefits.


Table of Contents

1. Prerequisites

2. Setting up the Angular Project

  • Installing Angular CLI

  • Creating a New Angular Project

  • Configuring Angular PWA

  • Adding Icons, Splash Screens, and Offline Support

3. Setting up the ASP.NET Core Backend

  • Installing the .NET Core SDK

  • Creating a New ASP.NET Core Web API Project

  • Configuring CORS and Authentication

  • Implementing Multi-Tenancy with Entity Framework Core

  • Building CRUD Operations and Business Logic

4. Integrating Angular PWA and ASP.NET Core Backend

  • Making HTTP Requests from Angular to ASP.NET Core

  • Authenticating Requests with JWT

  • Managing State with RxJS

  • Styling the Angular PWA with Angular Material

5. Conclusion


Building Dynamic PWAs in Angular and ASP.NET Core with a Multi-Tenant Project

Follow the below step-by-step guide for building dynamic PWAs in Angular and ASP.NET core with a Multi-tenant project:


Prerequisites

To follow along with this tutorial, ensure you have the following installed:

  • Angular CLI: You can install it globally by running npm install -g @angular/cli

  • .NET Core SDK: Download and install the SDK for your operating system from the official .NET Core website

  • SQL Server: Set up a local SQL Server database to store tenant-specific data

  • Visual Studio Code or Visual Studio: Choose your preferred code editor or IDE for development


Setting up the Angular Project

To create a dynamic PWA using Angular, we need to set up the Angular project and configure it to support PWA features, such as manifest.json, service workers, icons, splash screens, and offline support.


Let's go through the steps in detail.


STEP 1: Installing Angular CLI

Before we can create an Angular project, we need to install the Angular CLI (Command Line Interface), which provides us with various tools and commands for Angular development. Follow these steps to install Angular CLI globally:


Open a terminal or command prompt. Run the following command:

npm install -g @angular/cli

This command installs the Angular CLI package globally on your system.


STEP 2: Creating a New Angular Project

Once Angular CLI is installed, we can create a new Angular project by following these steps:


Open a terminal or command prompt. Run the following command:

ng new dynamic-pwa

This command creates a new Angular project named "dynamic-pwa".


After the project is created, navigate to the project directory by running:

cd dynamic-pwa

This command changes the current directory to the project directory.


STEP 3: Configuring Angular PWA

To enable PWA features in our Angular project, we need to configure it using Angular CLI. Follow these steps:


In the terminal or command prompt, make sure you are in the project directory. Run the following command:

ng add @angular/pwa

This command adds the necessary PWA features to our Angular project.


Angular CLI will automatically configure the manifest.json and service worker files for us. The manifest.json file contains metadata about the PWA, such as the app name, icons, and theme color. The service worker file enables caching and offline support for our application.


STEP 4: Adding Icons, Splash Screens, and Offline Support

To enhance the user experience of our PWA, we can add custom icons, and splash screens, and enable offline support. Follow these steps:


Open the project directory in your code editor.


Inside the src/assets directory, add the desired icons and splash screens in various sizes and formats. Make sure to follow the guidelines provided by the target platforms.


Open the src/manifest.json file and customize it according to your project's requirements. Update the app name, icons, theme color, and other relevant information.


To enable offline support, modify the src/ngsw-config.json file. You can define which files and resources should be cached for offline access.


By following these steps, you have successfully set up the Angular project, configured PWA features, and added icons, splash screens, and offline support to your dynamic PWA.


Setting up the ASP.NET Core Backend

In this section, we will go through the process of setting up the ASP.NET Core backend for our dynamic PWA with multi-tenancy.


STEP 1: Installing the .NET Core SDK

Before we begin, ensure that you have the .NET Core SDK installed on your machine. You can download and install it from the official .NET Core website (https://dotnet.microsoft.com/download).


STEP 2: Creating a New ASP.NET Core Web API Project

To create a new ASP.NET Core Web API project, follow these steps:


Run the following command to create a new ASP.NET Core Web API project named "MyApi":

dotnet new webapi -n MyApi

Navigate to the project directory using the following command:

cd MyApi

STEP 3: Configuring CORS and Authentication

To configure CORS and implement authentication mechanisms, follow these steps:


Open the project in your preferred code editor. Locate the Startup.cs file in the root directory.


Inside the ConfigureServices method, add the following code to configure CORS:

services.AddCors(options =>
{
    options.AddPolicy("AllowAll", builder =>
    {
        builder.AllowAnyOrigin()
               .AllowAnyMethod()
               .AllowAnyHeader();
    });
});

In the Configure method of the same file, add the following code to enable CORS:

app.UseCors("AllowAll");

Implement authentication mechanisms such as JWT or OAuth2 according to your requirements. You can refer to the ASP.NET Core documentation for detailed instructions on implementing authentication.


STEP 4: Implementing Multi-Tenancy with Entity Framework Core

To implement multi-tenancy using Entity Framework Core, follow these steps:


Install the required NuGet packages for Entity Framework Core and SQL Server. Open the terminal or command prompt and navigate to the project directory. Run the following command:

dotnet add package Microsoft.EntityFrameworkCore.SqlServer

Define tenant-specific models by creating classes that represent the entities for each tenant. For example, if you have a "Product" entity, create a separate class for each tenant like "Tenant1Product" and "Tenant2Product". Each tenant-specific class should inherit from a base "Product" class.


Configure multi-tenancy in the Startup.cs file by adding the following code inside the ConfigureServices method:

services.AddScoped<ITenantProvider, TenantProvider>();
services.AddDbContext<AppDbContext>((serviceProvider, options) =>
{
    var tenantProvider = serviceProvider.GetRequiredService<ITenantProvider>();
    var connectionString = Configuration.GetConnectionString(tenantProvider.GetTenantId());
    options.UseSqlServer(connectionString);
});

Implement migrations to create the tenant-specific database schema. Run the following command in the terminal or command prompt:

dotnet ef migrations add InitialCreate
dotnet ef database update

Make sure to run these commands whenever you add or modify tenant-specific models.


STEP 5: Building CRUD Operations and Business Logic

To build CRUD operations and business logic for each tenant, follow these steps:

  1. Create controllers to handle CRUD operations for each tenant. For example, create a Tenant1ProductsController and a Tenant2ProductsController, each with methods for creating, reading, updating, and deleting products specific to the corresponding tenant.

  2. Implement business logic specific to each tenant within the controllers or separate service classes. This can include additional validations, data manipulations, or any other tenant-specific requirements.

  3. Test and debug the API using tools like Postman to ensure the functionality of CRUD operations for each tenant.

By following these steps, you have successfully set up the ASP.NET Core backend for your dynamic PWA with multi-tenancy. In the next section, we will integrate the Angular PWA and the ASP.NET Core backend to create a cohesive application.


Integrating Angular PWA and ASP.NET Core Backend

In this section, we will explore how to integrate the Angular PWA with the ASP.NET Core backend. We will cover making HTTP requests, authenticating requests with JWT, managing the state with RxJS, and styling the Angular PWA using Angular Material.

STEP 1: Making HTTP Requests from Angular to ASP.NET Core To make HTTP requests from the Angular PWA to the ASP.NET Core backend, we can use the HttpClient module provided by Angular.

Import the HttpClient module in the Angular component where you want to make the HTTP request:

import { HttpClient } from '@angular/common/http'; 

Inject the HttpClient module into the component's constructor:

constructor(private http: HttpClient) { } 

Define the API endpoint URL:

const apiUrl = 'https://example.com/api'; 

Make the HTTP request using the appropriate method (get, post, put, delete, etc.) and handle the response:

this.http.get(`${apiUrl}/users`).subscribe(   
    (response) => {     
        console.log(response);   
    },   
    (error) => {     
        console.error(error);   
    } 
); 

STEP 2: Authenticating Requests with JWT To secure the communication between the Angular PWA and the ASP.NET Core backend, we can implement JWT (JSON Web Tokens) authentication.

In the ASP.NET Core backend, generate a JWT token upon successful authentication and include it in the response:

var token = GenerateJwtToken(user); 
return Ok(new { Token = token }); 

In the Angular PWA, store the received token securely (e.g., in local storage).

Attach the JWT token to the headers of the HTTP requests from the Angular PWA:

const headers = {  
  Authorization: `Bearer ${token}` 
};  

this.http.get(`${apiUrl}/users`, { headers }).subscribe(   
  (response) => {     
    console.log(response);   
  },   
  (error) => {     
    console.error(error);   
  } 
); 

In the ASP.NET Core backend, validate and decode the JWT token to ensure the authenticity of the requests:

var token = // Get the token from the request headers
var claimsPrincipal = ValidateJwtToken(token); 

STEP 3: Managing State with RxJS To manage state and data flow within the Angular PWA, we can leverage RxJS, a powerful library for reactive programming.

Import the necessary RxJS modules in the Angular component:

import { Observable } from 'rxjs'; 
import { map } from 'rxjs/operators'; 

Create an observable for a specific data source:

const users$: Observable<User[]> = this.http.get<User[]>(`${apiUrl}/users`); 

Subscribe to the observable and handle the emitted values:

users$.subscribe(   
    (users) => {     
        console.log(users);   
    },   
    (error) => {     
        console.error(error);   
    } 
); 

Utilize RxJS operators to transform and manipulate the emitted values:

users$   
    .pipe(     
        map((users) => users.filter((user) => user.age > 18))   
    )   
    .subscribe(     
        (filteredUsers) => {       
            console.log(filteredUsers);     
        },     
        (error) => {       
            console.error(error);     
        }   
    ); 

STEP 4: the Angular PWA with Angular Material Angular Material is a UI component library that provides ready-to-use, customizable components for building polished user interfaces.

Install Angular Material:

ng add @angular/material 

Import the necessary Angular Material modules in the app.module.ts file:

import { MatInputModule } from '@angular/material/input'; 
import { MatButtonModule } from '@angular/material/button'; 

// Import other necessary modules

Add the imported modules to the imports array in the app.module.ts file:

@NgModule({   
    imports: [     
        MatInputModule,     
        MatButtonModule,     
        // Other imported modules   
    ],   
    // Other configurations 
}) 

Use Angular Material components in your Angular templates:

<mat-form-field>
    <input matInput placeholder="Username">
</mat-form-field>

<button mat-button color="primary">Submit</button>

By following these steps, you can integrate the Angular PWA with the ASP.NET Core backend, make HTTP requests, authenticate requests with JWT, manage state with RxJS, and style the Angular PWA using Angular Material.


Conclusion

In this article, we explored the process of building a dynamic Progressive Web Application (PWA) using Angular and ASP.NET Core, with a focus on multi-tenant functionality. We covered setting up the Angular project, implementing multi-tenancy, configuring the ASP.NET Core backend, and serving the PWA. By following these steps and incorporating your own customizations, you can create powerful and dynamic PWAs that cater to multiple tenants in your project.

0 comments
bottom of page