Reader small image

You're reading from  Software Architecture with C# 12 and .NET 8 - Fourth Edition

Product typeBook
Published inFeb 2024
PublisherPackt
ISBN-139781805127659
Edition4th Edition
Right arrow
Authors (2):
Gabriel Baptista
Gabriel Baptista
author image
Gabriel Baptista

Gabriel Baptista has been working with software development since the beginning of .NET. Today, his main contributions are managing numerous projects for retail and industry. He is an Azure Platform-as-a-Service (PaaS) solution specialist, teaches at Computing Engineering universities, and helps tech startups as a mentor.
Read more about Gabriel Baptista

Francesco Abbruzzese
Francesco Abbruzzese
author image
Francesco Abbruzzese

Francesco Abbruzzese dedicates his life to his two great passions: software and powerlifting. He is the author of the MVC Controls Toolkit and the Blazor Controls Toolkit libraries. He has contributed to the diffusion and evangelization of the Microsoft web stack since the first version of ASP.NET. His company, Mvcct Team, offers web applications, tools, and services for web technologies. He has moved from AI systems, where he implemented one of the first decision support systems for financial institutions, to top-10 video game titles such as Puma Street Soccer.
Read more about Francesco Abbruzzese

View More author details
Right arrow

Implementing Frontend Microservices with ASP.NET Core

Chapter 14, Implementing Microservices with .NET, described general techniques for implementing microservices in .NET but focused mainly on worker microservices, that is, on microservices that perform background jobs without communicating with anything outside of the application.

Microservices that communicate with the world outside of the application bring with them other problems and need further techniques.

More specifically, microservices that communicate with a human user must implement a presentation layer, while microservices that expose APIs must conform to well-established standards and should preferably have documentation. Moreover, web APIs that target single-page applications (SPAs) must conform with browser policies; that is, either they are exposed on a single domain that is the same domain the SPA was downloaded from, or they must configure CORS policies. We will see how to address both CORS and issues...

Technical requirements

This chapter requires the free Visual Studio 2022 Community edition or better with all database tools installed.

The code samples necessary to clarify the concepts in this chapter will be taken from a practical example application based on the WWTravelClub book use case. The full example application is described in detail in the A front end microservice section of Chapter 21, Case Study. Its code is available at https://github.com/PacktPublishing/Software-Architecture-with-C-Sharp-12-and-.NET-8-4E.

Front-ends and micro-frontends

The main peculiarity of front-end microservices is that they need a robust web server that is able to optimize all the request/response handling and ensure the needed level of security. Moreover, high-traffic applications also need a load balancer.

Examples of services offered by robust web servers like IIS, Apache, and NGINX are:

  • Limiting access to just some file types and directories to prevent access to private files and to prevent remote file execution; that is, execution of server commands/scripts through web requests.
  • Blocking dangerous requests that might cause access to unwanted files or directories (path-traversal attacks).
  • Blocking requests that exceed a customizable length since they might cause a denial of service.
  • Logging and IP address blocking to discover and contrast hacker attacks.
  • Redirecting requests to the application associated with each URL.
  • Queueing requests and assigning them to available...

Defining the application architecture

The application will be implemented with the Domain-Driven Design (DDD) approach and associated patterns described in Chapter 7, Understanding the Different Domains in Software Solutions, and Chapter 13, Interacting with Data in C# – Entity Framework Core, so having a good understanding of the content covered in those chapters is a fundamental prerequisite to reading this chapter.

The application is organized based on a DDD approach and uses SOLID principles to map your domain sections. That is, the application is organized into three layers, each implemented as a different project:

  • There’s a domain layer, which contains the repository’s implementation and the classes describing database entities. It is a .NET library project. However, since it needs some interfaces, like IServiceCollection, which are defined in Microsoft.NET.Sdk.web, and since the DBContext layer must inherit from the identity framework in...

Defining the domain layer interface

Once the PackagesManagementDomain Standard 2.1 library project has been added to the solution, we’ll add a Tools folder to the project root. Then, we’ll place all the DomainLayer tools contained in the code associated with ch7. Since the code contained in this folder uses data annotations and defines DI extension methods, we must also add references to the System.ComponentModel.Annotations and Microsoft.Extensions.DependencyInjection.Abstration NuGet packages.

Then, we need an Aggregates folder containing all the aggregate definitions (which, as already said, we will implement as interfaces).

Below is an example of an aggregate definition:

public interface IPackage : IEntity<int>
{
    void FullUpdate(IPackageFullEditDTO packageDTO);
    string Name { get; set; }
    string Description { get;}
    decimal Price { get; set; }
    int DurationInDays { get; }
    DateTime? StartValidityDate { get;}
    DateTime? EndValidityDate...

Defining the domain layer implementation

The domain layer implementation contains the implementation of all repository interfaces and aggregate interfaces defined in the domain layer interface. In the case of .NET 8, it uses Entity Framework Core entities to implement aggregates. Adding a domain layer interface in between the domain layer’s actual implementation and the application layer decouples the application layer from EF and entity-specific details. Moreover, it conforms with the onion architecture, which, in turn, is an advised way to architect microservices.

The domain layer implementation project should contain references to Microsoft.AspNetCore.Identity.EntityFrameworkCore and Microsoft.EntityFrameworkCore.SqlServer NuGet packages, since we are using Entity Framework Core with SQL Server. It references Microsoft.EntityFrameworkCore.Tools and Microsoft.EntityFrameworkCore.Design, which is needed to generate database migrations, as explained in the Entity Framework...

Defining the application layer

The application layer contains the definition of all business operations. These business operations use data provided by the user to modify domain layer abstraction aggregates, such as touristic packages. When all business operations involved in the current user request have been performed, an IUnitOfWork.SaveEntitiesAsync() operation is performed to save all changes to the database.

As a first step, for simplicity, let’s freeze the application culture to en-US by adding the following code to the ASP.NET Core pipeline:

app.UseAuthorization();
// Code to add: configure the Localization middleware
var ci = new CultureInfo("en-US");
app.UseRequestLocalization(new RequestLocalizationOptions
{
    DefaultRequestCulture = new RequestCulture(ci),
    SupportedCultures = new List<CultureInfo>
    {
        ci,
    },
     SupportedUICultures = new List<CultureInfo>
    {
        ci,
    }
});

As a second step, we can...

Defining controllers

Each controller interacts with a use case that emerged in the analysis stage with its action methods. Action methods do their job by requiring command handlers and query interfaces from the dependency injection engine.

Below is an example of how query objects are required and used:

[HttpGet]
public async Task<IActionResult> Index(
    [FromServices] IPackagesListQuery query)
{
    var results = await query.GetAllPackages();
    var vm = new PackagesListViewModel { Items = results };
    return View(vm);
}

Below, instead, is an example of the usage of command handlers:

public async Task<IActionResult> Edit(
    PackageFullEditViewModel vm,
    [FromServices] ICommandHandler<UpdatePackageCommand> command)
{
    if (ModelState.IsValid)
    {
        await command.HandleAsync(new UpdatePackageCommand(vm));
        return RedirectToAction(
            nameof(ManagePackagesController.Index));
    }
    else
        return View(vm)...

Summary

In this chapter, we analyzed the peculiarities of front-end microservices and the techniques used to implement them.

Then, we put together the techniques learned in this chapter and in previous chapters in the complete implementation of a front-end microservice.

We used an onion architecture with a data layer and a domain layer abstraction, and we implemented each as a separate project. The application layer and the presentation layer were implemented together in the same ASP.NET Core MVC project.

The microservice used the CQRS pattern and used a queue implemented with a database table to store the events to send to other microservices.

The next chapter explains how to implement a presentation layer with client-based techniques. We will use Blazor as an example client framework.

Questions

  1. What is the difference between a front-end and an API gateway?
  2. Why should all front-ends and API gateways use a robust web server?
  3. Why should complex blocking database transactions be avoided?
  4. When does the concurrency technique ensure a better performance?
  5. What is the advantage of using domain events to implement interactions between different aggregates?

Further reading

Since this chapter just put into practice concepts explained in other chapters (mainly Chapter 7, Understanding the Different Domains in Software Solutions, Chapter 11, Applying a Microservice Architecture to Your Enterprise Application, and Chapter 13, Interacting with Data in C# – Entity Framework Core), here we will include just a few links on how to use API gateways and further information on the MediatR library, which was mentioned in the example:

lock icon
The rest of the chapter is locked
You have been reading a chapter from
Software Architecture with C# 12 and .NET 8 - Fourth Edition
Published in: Feb 2024Publisher: PacktISBN-13: 9781805127659
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
undefined
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at €14.99/month. Cancel anytime

Authors (2)

author image
Gabriel Baptista

Gabriel Baptista has been working with software development since the beginning of .NET. Today, his main contributions are managing numerous projects for retail and industry. He is an Azure Platform-as-a-Service (PaaS) solution specialist, teaches at Computing Engineering universities, and helps tech startups as a mentor.
Read more about Gabriel Baptista

author image
Francesco Abbruzzese

Francesco Abbruzzese dedicates his life to his two great passions: software and powerlifting. He is the author of the MVC Controls Toolkit and the Blazor Controls Toolkit libraries. He has contributed to the diffusion and evangelization of the Microsoft web stack since the first version of ASP.NET. His company, Mvcct Team, offers web applications, tools, and services for web technologies. He has moved from AI systems, where he implemented one of the first decision support systems for financial institutions, to top-10 video game titles such as Puma Street Soccer.
Read more about Francesco Abbruzzese