Welcome to the third part of our series on building large-scale applications using .NET and Angular! In this, we’ll explore advanced Angular routing techniques, caching in .NET using Redis, and deployment strategies for your application. These topics are essential for optimizing performance, improving user experience, and ensuring your application is in production.
If you not have a member on Medium, read from here
Recap of Part 2
In Part 2, we covered:
- State Management in Angular using NgRx for predictable state management.
- Authentication and Authorization in .NET using JWT tokens.
- Real-Time Communication with SignalR for live updates.
If you missed Part 2, I recommend checking it out before proceeding.
1. Advanced Angular Routing
As your Angular application grows, managing routes efficiently becomes critical. Let’s explore some advanced routing techniques to improve performance and user experience.
#Lazy Loading
Lazy loading allows you to load feature modules on demand, reducing the initial load time of your application.
Example: Lazy Loading a Feature Module
- Define a Feature Module:
Create a feature module for tasks.
// app/features/tasks/tasks.module.ts
import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { TaskListComponent } from './components/task-list.component';
@NgModule({
declarations: [TaskListComponent],
imports: [
RouterModule.forChild([
{ path: '', component: TaskListComponent }
])
]
})
export class TasksModule {}
2. Lazy Load the Module:
Update your app-routing.module.ts to lazy load the tasks module.
// app/app-routing.module.ts
const routes: Routes = [
{ path: 'tasks', loadChildren: () => import('./features/tasks/tasks.module').then(m => m.TasksModule) },
{ path: '', redirectTo: '/tasks', pathMatch: 'full' }
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule {}
#Route Guards
Route guards allow you to control access to routes based on certain conditions (e.g., authentication).
Example: Auth Guard
- Create an Auth Guard:
Implement a guard to restrict access to authenticated users.
// app/core/guards/auth.guard.ts
import { Injectable } from '@angular/core';
import { CanActivate, Router } from '@angular/router';
import { AuthService } from '../services/auth.service';
@Injectable({
providedIn: 'root'
})
export class AuthGuard implements CanActivate {
constructor(private authService: AuthService, private router: Router) {}
canActivate(): boolean {
if (this.authService.isAuthenticated()) {
return true;
} else {
this.router.navigate(['/login']);
return false;
}
}
}
2. Apply the Guard:
Protect the tasks route with the AuthGuard.
// app/app-routing.module.ts
const routes: Routes = [
{ path: 'tasks', loadChildren: () => import('./features/tasks/tasks.module').then(m => m.TasksModule), canActivate: [AuthGuard] },
{ path: 'login', component: LoginComponent },
{ path: '', redirectTo: '/tasks', pathMatch: 'full' }
];
#Preloading Strategies
Preloading allows you to load feature modules in the background while the user interacts with the application.
Example: PreloadAllModules
Enable preloading in your AppRoutingModule.
// app/app-routing.module.ts
import { PreloadAllModules } from '@angular/router';
@NgModule({
imports: [RouterModule.forRoot(routes, { preloadingStrategy: PreloadAllModules })],
exports: [RouterModule]
})
export class AppRoutingModule {}
2. Caching in .NET with Redis
Caching is a powerful technique to improve the performance of your application by storing frequently accessed data in memory. Redis is a popular in-memory data store that can be used for distributed caching.
#Setting Up Redis
- Install Redis:
Install Redis on your machine or use a cloud provider like Azure Redis Cache. - Install the Redis NuGet Package:
Add the Redis package to your .NET project.
dotnet add package Microsoft.Extensions.Caching.StackExchangeRedis
3. Configure Redis in .NET:
Update Startup.cs or Program.cs configure Redis.
// Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddStackExchangeRedisCache(options =>
{
options.Configuration = "localhost:6379"; // Redis server connection string
});
services.AddControllers();
}
#Using Redis Cache
- Inject the Cache:
InjectIDistributedCacheinto your service.
// Services/TaskService.cs
public class TaskService : ITaskService
{
private readonly IDistributedCache _cache;
private readonly ITaskRepository _taskRepository;
public TaskService(IDistributedCache cache, ITaskRepository taskRepository)
{
_cache = cache;
_taskRepository = taskRepository;
}
public async Task<IEnumerable<TaskDto>> GetAllTasksAsync()
{
var cacheKey = "AllTasks";
var cachedTasks = await _cache.GetStringAsync(cacheKey);
if (cachedTasks != null)
{
return JsonSerializer.Deserialize<IEnumerable<TaskDto>>(cachedTasks);
}
var tasks = await _taskRepository.GetAllAsync();
var taskDtos = tasks.Select(t => new TaskDto
{
Id = t.Id,
Title = t.Title,
Description = t.Description
});
await _cache.SetStringAsync(cacheKey, JsonSerializer.Serialize(taskDtos), new DistributedCacheEntryOptions
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(10) // Cache for 10 minutes
});
return taskDtos;
}
}
3. Deployment Strategies
Deploying your application to production requires careful planning. Let’s explore some deployment strategies.
#Dockerizing Your Application
Docker allows you to package your application and its dependencies into a container, ensuring consistency across environments.
- Create a Dockerfile for .NET:
Add aDockerfileto your .NET project.
# Use the official .NET image
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80
# Build the application
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY . .
RUN dotnet publish -c Release -o /app
# Final stage
FROM base AS final
WORKDIR /app
COPY --from=build /app .
ENTRYPOINT ["dotnet", "MyApp.Backend.dll"]
2. Create a Dockerfile for Angular:
Add a Dockerfile to your Angular project.
# Use the official Node image
FROM node:16 AS build
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build -- --prod
# Use the official Nginx image
FROM nginx:alpine
COPY --from=build /app/dist/my-app /usr/share/nginx/html
EXPOSE 80
3. Deploy to the Cloud:
Use platforms like Azure, AWS, or Google Cloud to deploy your Docker containers.
What’s Next?
In Part 4, we’ll dive into:
- Performance Optimization: Techniques for improving the performance of your .NET and Angular applications.
- Logging and Monitoring: Implementing logging and monitoring for better observability.
- CI/CD Pipelines: Setting up continuous integration and deployment pipelines.
Stay tuned, and happy coding! 😊


















