Search icon CANCEL
Cart icon
Close icon
You have no products in your basket yet
Save more on your purchases!
Savings automatically calculated. No voucher code required
Arrow left icon
All Products
Best Sellers
New Releases
Learning Hub
Free Learning
Arrow right icon
Software Architecture with C# 12 and .NET 8 - Fourth Edition
Software Architecture with C# 12 and .NET 8 - Fourth Edition

Software Architecture with C# 12 and .NET 8: Build enterprise applications using microservices, DevOps, EF Core, and design patterns for Azure, Fourth Edition

€29.99 €20.98
€14.99 Monthly

What do you get with eBook?

Product feature icon Instant access to your Digital eBook purchase
Product feature icon Download this book in EPUB and PDF formats
Product feature icon AI Assistant (beta) to help accelerate your learning
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
Buy Now
Table of content icon View table of contents Preview book icon Preview Book

Software Architecture with C# 12 and .NET 8 - Fourth Edition

Understanding the Importance of Software Architecture

We started writing this book in 2018. It has been five years since the publication of the first edition, and the importance of software architecture for creating enterprise applications (EAs) that attend to our customers’ needs has only grown. Besides, technology itself is evolving at a speed that is hard to follow, and for this reason, new architectural opportunities keep emerging. So, we keep saying that the more we build complex and fantastic solutions, the more we need great software architectures to build and maintain them.

We are sure that is the reason why you decided to read this new edition of the book, and this is the reason why we decided to write it. It is not only a matter of how .NET 8 is different from .NET 6, because there are other incredible books that take this approach. It is truly the purpose of delivering to the community a book that can support developers and software architects in the difficult decision of what component to use while designing a solution. For this reason, in this new edition, we have reformulated the way we present all the content.

You will find while reading the chapters of this new edition that you will be given support for understanding the fundamentals and technology topics that are unavoidable when designing enterprise applications using .NET 8, C#, and cloud computing. Most of the examples will use Microsoft Azure, but we will always present this content in a way that you are not locked into a specific cloud platform.

It is important to remind you that it is not a simple task to write about this important subject, which offers so many alternative techniques and solutions. The main objective of this book is not to build an exhaustive and never-ending list of available techniques and solutions but to show how various families of techniques are related, and how they impact, in practice, the construction of a maintainable and sustainable solution. We hope you all enjoy this new journey!

Specifically, in Chapter 1, Understanding the Importance of Software Architecture, we will discuss how the need to keep our focus on creating effective enterprise solutions continuously increases; users always need more new features in their applications. Moreover, the need to deliver frequent application versions (due to a quickly changing market) increases our obligation to have sophisticated software architecture and development techniques.

The following topics will be covered in this chapter:

  • What software architecture is
  • Some software development process models that may help you as a software architect
  • The process for gathering the right information to design high-quality software
  • Design techniques for helping in the process of development
  • Cases where the requirements impact the system results

For this new edition, we have also reformulated the way we will present the case study of the book. You will find it in a single chapter, at the end of the book, where it will be easy for you to understand the whole purpose of its implementation.

The case study of this book will take you through the process of creating the software architecture for a travel agency called World Wild Travel Club (WWTravelClub). The purpose of this case study is to help you understand the theory explained in each chapter and to provide an example of how to develop an enterprise application with Azure, Azure DevOps, GitHub, C# 12, .NET 8, ASP.NET Core, and other technologies that will be introduced in this book.

By the end of this chapter, you will understand exactly what the mission of software architecture is. You will also have learned what Azure is and how to create an account on the platform. You will also have received an overview of software processes, models, and other techniques that will enable you to lead your team.

What is software architecture?

That you are reading this book today is thanks to the computer scientists who decided to consider software development as an engineering area. This happened in the last century, more specifically, at the end of the sixties, when they proposed that the way we develop software is quite like the way we construct buildings. That is why we have the name software architecture. Just as an architect designs a building and oversees its construction based on that design, the main goal of a software architect is to ensure that the software application is implemented well; and good implementation requires the design of a great architectural solution.

In a professional development project, you must do the following things:

  • Define the customer requirements for the solution.
  • Design a great solution to meet those requirements.
  • Implement the designed solution.
  • Test the solution implementation.
  • Validate the solution with your customer.
  • Deliver the solution in the working environment.
  • Maintain the solution afterward.

Software engineering defines these activities as the software development lifecycle fundamentals. All the theoretical software development process models (waterfall, spiral, incremental, agile, and so on) are somehow related to this cycle. No matter the model you use, if you do not perform the essential tasks in the initial stages of your project, you will not deliver acceptable software as a solution.

The main point about designing great solutions is foundational to the purpose of this book. You must understand that great real-world solutions bring with them a few fundamental constraints:

  • The solution needs to meet user requirements.
  • The solution needs to be delivered on time.
  • The solution needs to adhere to the project budget.
  • The solution needs to deliver good quality.
  • The solution needs to guarantee safe and effective future evolution.

Great solutions need to be sustainable, and you must understand that there is no sustainable software without great software architecture. Nowadays, great software architecture depends on both modern tools and modern environments to perfectly fit users’ requirements.

For this reason, this book will use some great tools provided by Microsoft. We decided to write the book always following the long-term support (LTS) versions, which is why we are now applying all the examples using .NET 8. This is the second LTS version as a unified platform for software development, which gives us a great opportunity to create fantastic solutions.

Linha do tempo  Descrição gerada automaticamente

Figure 1.1: .NET support

.NET 8 is delivered together with C# 12. Considering the .NET approach of targeting so many platforms and devices, C# is now one of the most used programming languages in the world and runs on everything from small devices up to huge servers in different operating systems (OSs) and environments.

The book will also use Microsoft Azure, which is Microsoft’s cloud platform, where you will find all the components the company provides to build advanced software architecture solutions.

It is worth mentioning that the use of .NET 8 with Azure was just an option chosen by the authors. .NET can work just as well using other cloud providers, and Azure can handle other coding frameworks very well.

To be a software architect, you need to be familiar with these technologies, and many others too. This book will guide you on a journey where, as a software architect working in a team, you will learn how to provide optimal solutions using these tools. Let us start this journey by creating your Azure account.

Creating an Azure account

Microsoft Azure is one of the best cloud solutions currently available on the market. It is important to know that, inside Azure, we will find a selection of components that can help us define the architecture of twenty-first-century solutions.

If you want to check Azure’s current state, structure, and updates in a compact, digestible way, just go to, developed by Alexey Polkovnikov. The content is continuously updated so you can revisit it to learn, evaluate, or even just have fun with the dozens of Azure components described in this Azure encyclopedia.

This subsection will guide you in creating an Azure account. If you already have one, you can skip this part.

  1. First, go to There, you will find the information you need to start your subscription. Translation to your native language is usually set automatically.
  2. Once you have accessed this portal, it is possible to sign up. If you have never done this before, there is a Start free option, so you will be able to use some Azure features without spending any money. Please check the options for free plans at
  3. The process for creating a free account is quite simple, and you will be guided by a form that requires you to have a Microsoft account or GitHub account.
  4. During the process, you will also be asked for a credit card number to verify your identity and to keep out spam and bots. However, you will not be charged unless you upgrade the account.
  5. To finish the assignment, you will need to accept the subscription agreement, offer details, and privacy statement.
  6. Once you have finished filling out the form, you will be able to access the Azure portal. As you can see in the following screenshot, the panel shows a dashboard that you can customize, and a menu on the left, where you can set up the Azure components you are going to use in your solution. Throughout this book, we will come back to this screen to set up the components needed to help us create modern software architecture. To find the next page, just select the hamburger menu icon and click on All services:

Figure 1.2: The Azure portal

Once you have created your Azure account, you are ready to find out how a software architect can lead a team to develop software, taking advantage of all the opportunities offered by Azure. However, it is important to keep in mind that a software architect needs to go beyond just technologies because they are expected to define how the software will be delivered.

Today, a software architect not only designs the basis of a piece of software but also determines how the whole software development and deployment process is conducted. The next section will cover some of the most widely used software development paradigms in the world. We will start by describing what the community refers to as traditional software engineering. After that, we will cover the agile models that have changed the way we build software nowadays.

Software development process models

As a software architect, it is important for you to understand some of the common development processes that are currently used in most enterprises. A software development process defines how people in a team produce and deliver software. In general, this process relates to a software engineering theory called the software development process model. Ever since software development was first defined as an engineering process, many process models for developing software have been proposed. Let us review the traditional software models, and then look at the agile ones that are currently common.

Reviewing traditional software development process models

Some of the models introduced in software engineering theory are already considered traditional and obsolete. This book does not aim to cover all of them, but here, we will give a brief explanation of the ones that are still used in some companies – the waterfall and incremental models.

Understanding the waterfall model principles

This topic may appear strange in a software architecture book from 2023, but yes, you may still find companies where the most traditional software process model remains the guideline for software development. This process executes all fundamental tasks in sequence. Any software development project consists of the following steps:

  • Requirements: where a product requirements document is created, and it is the basis for the software development process
  • Design: where the software architecture is developed according to the requirements
  • Implementation: where the software is programmed
  • Verification: where tests are performed in the application
  • Maintenance: where the cycle starts again after delivery

Let us look at a diagrammatic representation of this:

Diagram  Description automatically generated

Figure 1.3: The waterfall development cycle (

Often, the use of waterfall models causes problems such as delays in the delivery of a functional version of the software and user dissatisfaction due to the distance between expectations and the final product delivered. Besides, in my experience, having application tests start only after the completion of development always feels terribly stressful.

Analyzing the incremental model

Incremental development is an approach that tries to overcome the biggest problem of the waterfall model: the user can test the solution only at the end of the project. The idea of a model following this approach is to give the users opportunities to interact with the solution as early as possible so that they can give useful feedback, which will help during the development of the software.

A picture containing text  Description automatically generated

Figure 1.4: The incremental development cycle (

The incremental model presented in the preceding picture was introduced as an alternative to the waterfall approach. The idea of the model is to run for each increment a set of practices related to software development (communication, planning, modeling, construction, and deployment). Although it mitigated problems related to the lack of communication with the customer, fewer increments were still a problem for big projects because the increments were still too long.

When the incremental approach was used on a large scale – mainly at the end of the last century – many problems related to project bureaucracy were reported, due to the large amount of documentation required. This clunky scenario caused the rise of a very important movement in the software development industry – agile.

Understanding agile software development process models

At the beginning of this century, developing software was considered one of the most chaotic activities in engineering. The percentage of software projects that failed was incredibly high, and this fact proved the need for a different approach to deal with the flexibility required by software development projects.

In 2001, the Agile Manifesto was introduced to the world, and from that time forward various agile process models were proposed. Some of them have survived up until now and are still very common.

The Agile Manifesto has been translated into more than 60 languages. You can check it out at

One of the biggest differences between agile models and traditional models is the way developers interact with the customer. The message behind all agile models is that the faster you deliver software to the user, the better. This idea is sometimes confusing for software developers who understand this as – Let’s try coding, and that’s all, folks!

However, there is an important observation of the Agile Manifesto that many people do not read when they start working with agile:

Figure 1.5: Manifesto for agile software development

A software architect always needs to remember this. Agile processes do not mean a lack of discipline. Moreover, when you use the agile process, you will quickly understand that there is no way to develop good software without discipline. On the other hand, as a software architect, you need to understand that soft means flexibility. A software project that refuses to be flexible tends to ruin itself over time.

The 12 principles behind agile are foundational to this flexible approach:

  1. Continuously delivering valuable software to satisfy the customer must be the highest priority of any developer.
  2. Changing requirements needs to be understood as an opportunity to make the customer more competitive.
  3. Use a weekly timescale to deliver software.
  4. A software team must be composed of businesspeople and developers.
  5. A software team needs to be trusted and should have the correct environment to get the project done.
  6. The best way to communicate with a software team is face to face.
  7. You can see the greatest software team achievement when the software is really working in production.
  8. Agile works properly when it delivers sustainable development.
  9. The more you invest in techniques and good design, the more agile you are.
  10. Simplicity is essential.
  11. The more self-organized the teams are, the better-quality delivery you will have.
  12. Software teams tend to improve their behavior from time to time, analyzing and adjusting their process.

Even 20 years after the launch of the Agile Manifesto, its importance and connection to the current needs of software teams remain intact. Certainly, there are many companies where this approach is not fully accepted, but as a software architect, you should understand this as an opportunity to transform practices and evolve the team you are working with.

There are many techniques and models that were presented to the software community with the agile approach. The next subsections will discuss lean software development, extreme programming, and Scrum, so that you can decide as a software architect which ones you might use to improve your software delivery.

Lean software development

After the Agile Manifesto, the approach of lean software development was introduced to the community as an adaptation of a well-known movement in automobile engineering, Toyota’s model for building cars. The lean manufacturing method delivers a high level of quality even with few resources.

Mary and Tom Poppendieck mapped seven lean principles for software development, really connected to agile and the approach of many companies of this century, which are listed here:

  • Eliminate waste: You may consider waste to be anything that will interfere with the delivery of the real need of the customer.
  • Build quality in: An organization that wants to guarantee quality needs to promote it in processes from the very beginning, instead of only considering it when code is being tested.
  • Create knowledge: All companies that have achieved excellence have a common pattern of generating new knowledge by disciplined experimentation, documenting that knowledge, and guaranteeing that it is spread all over the organization.
  • Defer commitment: Plan decisions at the latest possible moment without causing damage to the project.
  • Deliver fast: The faster you deliver software, the more elimination of waste you have. Companies that compete using time frequency have significant advantages over their competitors.
  • Respect people: Giving reasonable objectives to the team, together with plans that will guide them to self-organize their routine, is a matter of respecting the people that you work with.
  • Optimize the whole: A lean company improves the cycle of value; from the moment it receives a new requirement to the point at which it delivers the software.

Following the lean principles helps a team or company to improve the quality of the features that are delivered to the customer. It also creates a reduction in time spent on features that will not be used by the customer. In lean, deciding the features that are important to the customer guides the team in delivering software that matters, and this is exactly what the Agile Manifesto intends to promote in software teams.

Extreme programming

Just before the release of the Agile Manifesto, some of the participants who designed the document, especially Kent Beck, presented to the world the extreme programming (XP) methodology for developing software.

XP is based on the values of simplicity, communication, feedback, respect, and courage. It was considered later as a social change in programming, according to Beck in his second book about the topic. It certainly promotes a huge change in the flow of development.

XP states that every team should simply do only what it was asked to do, communicating face to face daily, demonstrating the software early to get feedback, respecting the expertise of each member of the team, and having the courage to tell the truth about progress and estimates, considering the team’s work as a whole.

XP also delivers a set of rules. These rules may be changed by the team if they detect something is not working properly, but it is important to always maintain the values of the methodology.

These rules are divided into planning, managing, designing, coding, and testing. Don Wells has mapped XP at Although some of the ideas of the methodology were criticized strongly by many companies and specialists, there are many good practices that are still used nowadays:

  • Writing software requirements using user stories: User stories are considered an agile approach to describing user needs, together with acceptance tests, which are used to guarantee the correct implementation.
  • Divide software into iterations and deliver small releases: The practice of iterating in software development is implemented by all methodologies aside from waterfall. The fact of delivering faster versions decreases the risk of not meeting the customer’s expectations.
  • Avoid working overtime and guarantee a sustainable velocity: Although this must be one of the hardest tasks a software architect may deal with, overtime indicates that something is not working properly in the process.
  • Keep things simple: While developing solutions, it is quite common to try to anticipate features that the customer would like to have. This approach increases the complexity of the development and the time to market the solution. A different approach will cause high costs, and probably a low level of features that are used in the system you are developing.
  • Refactoring: The approach of refactoring the code continuously is good because it enables the evolution of your software and guarantees the design improvement that will truly be necessary due to the normal technical changes of the platforms you use to develop.
  • Keep the customer always available: If you follow XP, you should have an expert customer inside your team. This is certainly something that is hard to do, but the main idea of this approach is to guarantee that the customer is involved in all parts of development. As another bonus, having the customer close to your team means they understand the difficulties and expertise the team has, enabling an increase in trust between the parties.
  • Continuous integration: This practice is one of the bases of the current DevOps approach. The less difference you have between your personal code repository and the main code repository, the better.
  • Code the unit test first: A unit test is an approach where you program specific code for testing a single unit (class/method) of your project. This is discussed in a current development methodology called Test-Driven Development (TDD). The main goal here is to guarantee that every business rule has its own unit test case.
  • Code must be written to agreed standards: The need to determine standards for coding is connected to the idea that no matter which developer you have working on a specific part of the project, the code must be written so that any of them will understand it.
  • Pair programming: Pair programming is another difficult approach to achieve in every single minute of a software project, but the technique itself – one programmer coding and the other actively observing and offering comments, criticism, and advice – is useful in critical scenarios.
  • Acceptance tests: The adoption of acceptance tests to meet user stories is a good way to guarantee that newly released versions of the software do not cause damage to its current needs. An even better option is to have these acceptance tests automated.

It is worth mentioning that many of these rules are today considered vital practices in different software development methodologies, including DevOps and Scrum. We will discuss DevOps later in this book, in Chapter 8, Understanding DevOps Principles and CI/CD. Let us get into the Scrum model right now.

Getting into the Scrum model

Scrum is an agile model for the management of software development projects. The model comes from lean principles and is one of the more widely used approaches for developing software nowadays.

Please check out this link for more information about the Scrum framework:

As you can see in the following figure, the basis of Scrum is that you have a flexible backlog of user requirements (Product Backlog) that needs to be discussed in each agile cycle, called a Sprint. The Sprint goal (Sprint Backlog) is determined by the Scrum Team, composed of the Product Owner, the Scrum Master, and the Development Team. The Product Owner is responsible for prioritizing what will be delivered in that Sprint. During the Sprint, this person will help the team to develop the required features. The person who leads the team in the Scrum process is called the Scrum Master. All the meetings and processes are conducted by this person.

Diagram  Description automatically generated

Figure 1.6: The Scrum process

It is common to apply Scrum together with another agile technique, called Kanban, also developed by Toyota for manufacturing cars and commonly used for software maintenance. The main purpose of Kanban is to enable a visual system to make sure everybody understands what is going on in the product that is being developed. The famous Kanban board is an incredible way to do so, where you define what the team must do, what they are doing, and the things that are already done.

It is important to note that the Scrum process does not discuss how the software needs to be implemented, nor which activities will be done. Again, you must remember the basis of software development, discussed at the beginning of this chapter; Scrum needs to be implemented together with a process model. DevOps is one of the approaches that may help you use a software development process model together with Scrum. Check out Chapter 8, Understanding DevOps Principles and CI/CD, to understand it better.

Scaling agile throughout a company

Today it is quite common to find companies where agility is being practiced and evolving in a good way, considering the results of the techniques presented in the previous sections. The mixture of Scrum, Kanban, and XP, together with the evolution of the maturity of the software development process, has brought good results for companies and we have a world where software development is one of the key strategies for the success of a business.

Some companies naturally need to scale up the number of teams, but the important question in this process is how to evolve without missing agility. And you can be sure that this question may be addressed to you, as a software architect. You may find in SAFe® – Scaled Agile Framework a good answer to this question:

SAFe® for LeanEnterprises is a knowledge base of proven, integrated principles, practices, and competencies for achieving business agility using Lean, Agile, and DevOps.”

– Dean Leffingwell, creator.

© Scaled Agile, Inc.

Based on the core values of alignment, built-in quality, transparency, and program execution, the framework provides a detailed path for delivering products with the agility needed in companies where you have one or more value streams. Its principles enable agility and incremental delivery, system thinking, fast and economic decisions, and mainly, organization around value.

As a software architect, you may find opportunities for growth, considering you can work as a software architect in a system team, a system architect in an agile release train, or even an enterprise architect in the company. For sure, this will require a lot of studying and dedication, but this structure is what you will find in big companies.

As with every framework, technique, or model that you will find in this book, the purpose of presenting SAFe to you is not to cover every single detail of the content. You will find excellent material and training on their website. But as a software architect, understanding how to scale up a company may be good knowledge to have in your toolbelt! Now that you know it, let us go back to the stages of designing software with high quality, discussing how to gather the right information to design it.

Gathering the right information to design high-quality software

Fantastic! You’ve just started a software development project. Now, it is time to use all your knowledge to deliver the best software you can. Your first question is probably – How do I start? Well, as a software architect, you are going to be the one to answer that question. And you can be sure that your answer is going to evolve with each software project you lead.

Defining a software development process is the first task. This is generally done during the project planning process, or it might happen before it starts.

Another very important task is to gather the software requirements. No matter which software development process you decide to use, collecting real user needs is part of a difficult and continuous job. Of course, there are techniques to help you with this, and you can be sure that gathering requirements will help you to define important aspects of your software architecture.

These two tasks are considered by most experts in software development as the keys to success at the end of the development project journey. As a software architect, you need to enable them so that you can avoid as many problems as possible while guiding your team.

Understanding the requirements gathering process

There are many ways to represent the requirements. The most traditional approach consists of you having to write a perfect specification before the beginning of the analysis. Agile methods suggest instead that you need to write user stories as soon as you are ready to start a development cycle.

Remember that you do not write requirements just for the user; you write them for you and your team too.

The truth is that no matter the approach you decide to adopt in your projects, you will have to follow some steps to gather requirements. This is what we call the requirements engineering process.

Diagram  Description automatically generated

Figure 1.7: Requirements engineering process

During this process, you need to be sure that the solution is feasible. In some cases, the feasibility analysis is part of the project planning process too, and by the time you start the requirements elicitation, you will have the feasibility report already done. So, let us check the other parts of this process, which will give you a lot of important information about the software architecture.

Detecting exact user needs

There are a lot of ways to detect what exactly the user needs for a specific scenario. This process is known as elicitation. In general, this can be done using techniques that will help you to understand what we call user requirements. Here, you have a list of common techniques:

  • The power of imagination: If you are an expert in the area where you are providing solutions, you may use your own imagination to find new user requirements. Brainstorming can be conducted collaboratively so that a group of experts can define the user’s needs.
  • Questionnaires: This tool is useful for detecting common and important requirements such as the number and kind of users, peak system usage, and the most commonly used OS and web browser.
  • Interviews: Interviewing the users helps you as an architect to detect user requirements that perhaps questionnaires and your imagination will not cover.
  • Observation: There is no better way to understand the daily routine of a user than observing them for a day.

As soon as you apply one or more of these techniques, you will have great and valuable information about the user’s needs.

Remember that you can use these techniques in any situation where the real need is to gather requirements, no matter whether it is for the whole system or for a single story.

At that moment, you will be able to start analyzing these user needs and detecting the user and system requirements. Let us see how to do so in the next section.

Analyzing requirements

When you have detected the user needs, it is time to begin analyzing the requirements. To do so, you can use techniques such as the following:

  • Prototyping: Prototypes are fantastic to clarify and materialize the system requirements. Today, we have many tools that can help you to mock interfaces. A nice open-source tool is the Pencil Project. You will find further information about it at Figma ( is also a good tool for prototyping and they provide a starter pack that is free forever.
  • Use cases: The Unified Modeling Language (UML) use case model is an option if you need detailed documentation. The model is composed of a detailed specification and a diagram. Lucidchart ( is another good tool that can help you out with this. You can see the model created in Figure 1.8:
Diagrama  Descrição gerada automaticamente

Figure 1.8: Use case diagram example

While you are analyzing the requirements of the system, you will be able to clarify exactly what the user’s needs are. This is helpful when you are not sure about the real problem you need to solve, and it is much better than just starting to program the system and hoping for the best. Time invested in requirements analysis is time invested in better code later.

Writing the specifications

After you finish the analysis, it is important to register it as a specification. The specification document can be written using traditional requirements, or user stories, which are commonly used in agile projects.

A requirements specification represents the technical contract between the user and the team. There are some basic rules that this document needs to follow:

  • All stakeholders need to understand exactly what is written in the technical contract, even if they are not technicians.
  • The document needs to be clear.
  • You need to classify each requirement.
  • Use simple future tense to represent each requirement:
    • Bad example: A common user registers themselves.
    • Good example: A common user shall register themselves.
  • Ambiguity and controversy need to be avoided.
  • Some additional information can help the team to understand the context of the project they are going to work on. Here are some tips about how to add useful information:
    • Write an introductory chapter to give a full idea of the solution.
    • Create a glossary to make understanding easier.
    • Describe the kind of user the solution will cover.
  • Write functional and non-functional requirements:

    Functional requirements are quite simple to understand because they describe exactly what the software will do. On the other hand, non-functional requirements determine the restrictions related to the software, which means scalability, robustness, security, and performance. We will cover these aspects in the next section.

  • Attach documents that can help the user to understand the rules.

If you decide to write user stories, a good tip to follow is to write short sentences representing each moment in the system with each user, as follows:

As <user>, I want <feature>, so that <reason>

This approach will explain exactly the reason why that feature will be implemented. It is also a good tool to help you analyze the stories that are most important and prioritize the success of the project. They can also be great for informing the automated acceptance tests that should be built.

Understanding the principles of scalability, robustness, security, and performance

Detecting requirements is a task that will let you understand the software you are going to develop. However, as a software architect, you must pay attention to more than just the functional requirements for that system. Understanding the non-functional requirements is important, and one of the earliest activities for a software architect.

We are going to look at this in more detail in Chapter 2, Non-Functional Requirements, but at this point, it is important to know that the principles of scalability, robustness, security, and performance need to be applied to the requirements gathering process. Let us look at each concept:

  • Scalability: The Internet gives you the opportunity to have a solution with a great number of users all over the world. This is fantastic, but you, as a software architect, need to design a solution that provides that possibility. Scalability is the possibility for an application to increase its processing power as soon as it is necessary, due to the number of resources that are being consumed.
  • Robustness: No matter how scalable your application is, if it is not able to guarantee a stable and always-on solution, you are not going to get any peace. Robustness is important for critical solutions, where you do not have the opportunity to carry out maintenance at any time due to the kind of problem that the application solves. In many industries, the software cannot stop, and lots of routines run when nobody is available (overnight, during holidays, and so on). Designing a reliable solution will free you up to live your life while your software is running smoothly.
  • Security: This is another really important area that needs to be discussed after the requirements stage. Everybody worries about security, and different laws dealing with it are in place in different parts of the world. You, as a software architect, must understand that security needs to be provided by design. This is the only way to cope with all the needs that the security community is discussing right now.
  • Performance: The process of understanding the system you are going to develop will probably give you a good idea of what you will need to do to get the desired performance from the system. This topic needs to be discussed with the user, to identify most of the bottlenecks you will face during the development stage.

It is worth mentioning that all these concepts are requirements for the new generation of solutions that the world needs. What differentiates good software from incredible software is the amount of work done to meet the project requirements.

Reviewing the specification

Once you have the specification written, it is time to confirm with the stakeholders whether they agree with it. This can be done in a review meeting, or it can be done online using collaboration tools.

This is when you present all the prototypes, documents, and information you have gathered. As soon as everybody agrees with the specification, you are ready to start studying the best way to implement this part of your project.

It is worth mentioning that you might use the process described here for either the complete software or for just a small part of it.

Using design techniques as a helpful tool

Defining a solution is not easy. Determining which technology to use is also difficult. It is true that, during your career as a software architect, you will find many projects where your customer will bring you a solution ready for development. This can get quite complicated if you consider that solution as the correct solution; most of the time, there will be architectural and functional mistakes that will cause problems in the solution in the future.

There are some cases where the problem is worse – when the customer does not know the best solution for the problem. Some design techniques can help us with this, and we will introduce two of them here: Design Thinking and Design Sprint.

What you must understand is that these techniques can be a fantastic option to discover real requirements. As a software architect, you are committed to helping your team to use the correct tools at the correct time, and these tools may be the right options to ensure the project’s success.

Design Thinking

Design Thinking is a process that allows you to collect data directly from the users, focusing on achieving the best results to solve a problem. During this process, the team will have the opportunity to discover all the personas that will interact with the system. This will have a wonderful impact on the solution since you can develop the software by focusing on the user experience, which can have a fantastic impact on the results.

The process is based on the following steps:

  1. Empathize: In this step, you must execute field research to discover users’ concerns. This is where you find out about the users of the system. The process is good for making you understand why and for whom you are developing this software.
  2. Define: Once you have the users’ concerns, it is time to define their needs to solve them.
  3. Ideate: The needs will provide an opportunity to brainstorm some possible solutions.
  4. Prototype: These solutions can be developed as mock-ups to confirm whether they are good ones.
  5. Test: Testing the prototypes will help you to understand the prototype that is most connected to the real needs of the users.

The focus of a technique like this one is to accelerate the process of discerning the right product and considering the Minimum Viable Product (MVP). For sure, the prototype process will help stakeholders to understand the final product and, at the same time, engage the team to deliver the best solution.

Design Sprint

Design Sprint is a process focused on solving critical business questions through design in a five-day sprint. This technique was presented by Google, and it is something that allows you to quickly test and learn from an idea when you are looking to build and launch a solution to market.

The process involves experts spending a week to solve the problem at hand, in a war room prepared for that purpose. The week looks like this:

  • Monday: The focus of this day is to identify the target of the sprint and map the challenge to achieve it.
  • Tuesday: After understanding the goal of the sprint, participants start sketching solutions that may solve it. It is time to find customers to test the new solution that will be provided.
  • Wednesday: This is when the team needs to decide on the solutions that have the greatest chance of solving the problem. The team must draw these solutions into a storyboard, preparing a plan for the prototype.
  • Thursday: It is time to prototype the idea planned on the storyboard.
  • Friday: Having completed the prototype, the team presents it to customers, learning by getting information from their reactions to the solution designed.

As you can see, in both techniques, the acceleration of collecting reactions from customers comes from prototypes that will materialize your team’s ideas into something more tangible for the end user.

Common cases where the requirements gathering process impacts system results

All the information discussed up to this point in the chapter is useful if you want to design software following the principles of good engineering. Rather than advocating for traditional or agile development methods, the emphasis is on building software in a professional manner.

It is also a good idea to know about some cases in which failing to perform the activities you read about can cause some trouble for a software project. The following cases intend to describe what can go wrong, and how the preceding techniques can help a development team to solve the associated problems.

In most cases, very simple actions can guarantee better communication between the team and the customer, and this easy communication flow can transform a big problem into a real solution. Let us examine three common cases where requirements gathering can impact software performance, functionality, and usability.

Case 1 – my website is too slow to open that page!

Performance is one of the biggest problems that you as a software architect will deal with during your career. The reason why this aspect of any software is so problematic is that we do not have infinite computational resources to solve problems. The cost of computation is still high, especially if you are talking about software with a high number of simultaneous users.

You cannot solve performance problems by writing requirements. However, you will not end up in trouble if you write them correctly. The idea here is that requirements must present the desired performance of a system. A simple sentence describing this can help the entire team that works on the project:

Non-functional requirement: Performance – any web page of this software shall respond in at least 2 seconds, even when 1,000 users are accessing it concurrently.

The preceding sentence just lets everybody (users, testers, developers, architects, managers, and so on) know that any web page has a target to achieve. This is a good start, but it is not enough. A great environment for developing and deploying your application is also important. This is where .NET 8 can help you a lot; especially if you are talking about web apps, ASP.NET Core is considered one of the fastest options to deliver solutions today.

When it comes to performance, you, as a software architect, should consider the use of the techniques listed in the following sections together with specific tests to guarantee this non-functional requirement. It is also important to mention that ASP.NET Core will help you to use them easily, together with some Platform as a Service (PaaS) solutions delivered by Microsoft Azure.

Understanding backend caching

Caching is a great technique to avoid time-consuming and redundant queries. For instance, if you are fetching car models from a database, the number of cars in the database can increase, but the models themselves will not change. Once you have an application that constantly accesses car models, a good practice is to cache that information.

It is important to understand that a cache is stored in the backend and that cache is shared by the whole application (in-memory caching). A point to focus on is that when you are working on a scalable solution, you can configure a distributed cache using the Azure platform. In fact, ASP.NET provides both in-memory caching and distributed caching, so you can decide on the one that best fits your needs. Chapter 2, Non-Functional Requirements, covers scalability aspects in the Azure platform.

It is also important to mention that caching can happen in the frontend, in proxies along the way to the server, CDNs, and so on.

Applying asynchronous programming

When you develop ASP.NET applications, you need to keep in mind that your app needs to be designed for simultaneous access by many users. Asynchronous programming lets you do this simply, by giving you the keywords async and await.

The basic concept behind these keywords is that async enables any method to run asynchronously. On the other hand, await lets you synchronize the call of an asynchronous method without blocking the thread that is calling it. This easy-to-develop pattern will make your application run without performance bottlenecks and bring better responsiveness. This book will cover more about this subject in Chapter 2, Non-Functional Requirements.

Dealing with object allocation

One very good tip to avoid poor performance is to understand how the Garbage Collector (GC) works. The GC is the engine that will free memory automatically when you finish using it. There are some very important aspects of this topic, due to the complexity that the GC has.

Some types of objects are not collected by the GC if you do not dispose of them. The list includes any object that interacts with I/O, such as files and streaming. If you do not correctly use the C# syntax to create and destroy this kind of object, you will have memory leaks, which will deteriorate your application’s performance.

The incorrect way of working with I/O objects is:

System.IO.StreamWriter file = new System.IO.StreamWriter(@"C:\sample.txt");
file.WriteLine("Just writing a simple line");

The correct way of working with I/O objects is:

using System.IO.StreamWriter file = new System.IO.StreamWriter(@"C:\sample.txt");
file.WriteLine("Just writing a simple line");

It might be worth noting that this correct approach also ensures the file gets written (it calls FileStream.Flush() to dispose of its resources gracefully). In the incorrect example, the contents might not even be written to the file. Even though the preceding practice is mandatory for I/O objects, it is totally recommended that you keep doing this in all disposable objects. Indeed, using code analyzers in your solutions with warnings as errors will prevent you from accidentally making these mistakes! This will help the GC and will keep your application running with the right amount of memory. Depending on the type of object, mistakes here can snowball, and you could end up with other bad things on a bigger scale, for instance, port/connection exhaustion.

Another important aspect that you need to know about is that the time spent by the GC collecting objects will interfere with the performance of your app. Because of this, avoid allocating large objects and be careful with event handling and week references; otherwise, it can lead to you always waiting for the GC to finish its task.

Getting better database access

One of the most common performance Achilles’ heels is database access. The reason why this is still a big problem is a lack of attention paid while writing queries or lambda expressions to get information from a database. This book will cover Entity Framework Core in Chapter 13, Interacting with Data in C# – Entity Framework Core, but it is important to know what to choose and the correct data information to read from a database. Filtering columns and rows is imperative for an application that wants to deliver on performance.

The good thing is that best practices related to caching, asynchronous programming, and object allocation fit completely into the environment of databases. It is only a matter of choosing the correct pattern to get better-performing software.

Case 2 – the user’s needs are not properly implemented

The more technology is used in a wide variety of areas, the more difficult it is to deliver exactly what the user needs. Maybe this sentence sounds weird to you, but you must understand that developers, in general, study how to develop software, but they rarely study delivering the needs of a specific area. Of course, it is not easy to learn how to develop software, but it is even more difficult to understand a specific need in a specific area. Software development nowadays delivers software to all types of industries. The question here is how can a developer, whether a software architect or not, evolve enough to deliver software in the area they are responsible for?

Gathering software requirements will help you in this tough task; writing them will make you understand and organize the architecture of the system. There are several ways to minimize the risks of implementing something different from what the user really needs:

  • Prototyping the interface to achieve an understanding of the user interface faster
  • Designing the data flow to detect gaps between the system and the user operations
  • Frequent meetings to stay up to date on the user’s current needs and be aligned with incremental deliveries

Again, as a software architect, you will have to define how the software will be implemented. Most of the time, you are not going to be the one who programs it, but you will always be the one responsible for this. For this reason, some techniques can be useful to avoid the wrong implementation:

  • Requirements are reviewed by the developers to guarantee that they understand what they need to develop.
  • Code inspection to validate a predefined code standard. We will cover this in Chapter 4, Best Practices in Coding C# 12.
  • Meetings to eliminate impediments.

Remember, making sure the implementation matches the user’s needs is your responsibility. Use every tool you can to do so.

Case 3 – the usability of the system does not meet the user’s needs

Usability is a key point for the success of a software project. The way the software is presented and how it solves a problem will determine whether the user wants to use it or not. As a software architect, you must keep in mind that delivering software with good usability is mandatory nowadays.

There are basic concepts of usability that this book does not intend to cover, but a good way to meet the user’s needs when it comes to usability is by understanding who is going to use the software. Design Thinking can help you a lot with that, as was discussed earlier in this chapter.

Understanding the user will help you to decide whether the software is going to run on a web page, a cell phone, or even in the background. This understanding is very important to a software architect because the elements of a system will be better presented if you correctly map who will use them.

On the other hand, if you do not care about that, you will just deliver software that works. This can be good for a short time, but it will not exactly meet the real needs that made a person ask you to architect the software. You must keep in mind the options and understand that good software is software designed to run on many platforms and devices.

You will be happy to know that .NET 8 is an incredible cross-platform option for that. So, you can develop solutions to run your apps in Linux, Windows, Android, and iOS. You can run your applications on big screens, tablets, cell phones, and even drones! You can embed apps on boards for automation or in HoloLens for mixed reality. Software architects must be open-minded to design exactly what their users need.


In this chapter, you learned about the purpose of a software architect in a software development team. Also, this chapter covered the basics of software development process models and the requirements gathering process. You also had the opportunity to learn about how to create your Azure account, which will be used during the case study of this book. Moreover, you even learned about functional and non-functional requirements and how to create them using user stories. These techniques will help you deliver a better software project.

In the next chapter, you will have the opportunity to understand how important functional and non-functional requirements are to software architecture.


  1. What is the expertise that a software architect needs to have?
  2. How can Azure help a software architect?
  3. How does a software architect decide on the best software development process model to use in a project?
  4. How does a software architect contribute to gathering requirements?
  5. What kind of requirements does a software architect need to check in a requirements specification?
  6. How do Design Thinking and Design Sprint help a software architect in the process of gathering requirements?
  7. How do user stories help a software architect in the process of writing requirements?
  8. What are some good techniques to develop very good performance software?
  9. How does a software architect check whether a user requirement is correctly implemented?

Further reading

Here, we have listed some books and links you may consider using to gather more information about the topics covered in this chapter.

Learn more on Discord

To join the Discord community for this book – where you can share feedback, ask questions to the authors, and learn about new releases – follow the QR code below:

Left arrow icon Right arrow icon
Download code icon Download Code

Key benefits

  • Get introduced to software architecture fundamentals and begin applying them in .NET
  • Explore the main technologies used by software architects and choose the best ones for your needs
  • Master new developments in .NET with the help of a practical case study that looks at software architecture for a travel agency


Software Architecture with C# 12 and .NET 8 puts high-level design theory to work in a .NET context, teaching you the key skills, technologies, and best practices required to become an effective .NET software architect. This fourth edition puts emphasis on a case study that will bring your skills to life. You’ll learn how to choose between different architectures and technologies at each level of the stack. You’ll take an even closer look at Blazor and explore OpenTelemetry for observability, as well as a more practical dive into preparing .NET microservices for Kubernetes integration. Divided into three parts, this book starts with the fundamentals of software architecture, covering C# best practices, software domains, design patterns, DevOps principles for CI/CD, and more. The second part focuses on the technologies, from choosing data storage in the cloud to implementing frontend microservices and working with Serverless. You’ll learn about the main communication technologies used in microservices, such as REST API, gRPC, Azure Service Bus, and RabbitMQ. The final part takes you through a real-world case study where you’ll create software architecture for a travel agency. By the end of this book, you will be able to transform user requirements into technical needs and deliver highly scalable enterprise software architectures.

What you will learn

Program and maintain Azure DevOps and explore GitHub Projects Manage software requirements to design functional and non-functional needs Apply architectural approaches such as layered architecture and domain-driven design Make effective choices between cloud-based and data storage solutions Implement resilient frontend microservices, worker microservices, and distributed transactions Understand when to use test-driven development (TDD) and alternative approaches Choose the best option for cloud development, from IaaS to Serverless

Product Details

Country selected

Publication date : Feb 28, 2024
Length 756 pages
Edition : 4th Edition
Language : English
ISBN-13 : 9781805127659
Category :

What do you get with eBook?

Product feature icon Instant access to your Digital eBook purchase
Product feature icon Download this book in EPUB and PDF formats
Product feature icon AI Assistant (beta) to help accelerate your learning
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
Buy Now

Product Details

Publication date : Feb 28, 2024
Length 756 pages
Edition : 4th Edition
Language : English
ISBN-13 : 9781805127659
Category :

Table of Contents

26 Chapters
Preface Chevron down icon Chevron up icon
1. Understanding the Importance of Software Architecture Chevron down icon Chevron up icon
2. Non-Functional Requirements Chevron down icon Chevron up icon
3. Managing Requirements Chevron down icon Chevron up icon
4. Best Practices in Coding C# 12 Chevron down icon Chevron up icon
5. Implementing Code Reusability in C# 12 Chevron down icon Chevron up icon
6. Design Patterns and .NET 8 Implementation Chevron down icon Chevron up icon
7. Understanding the Different Domains in Software Solutions Chevron down icon Chevron up icon
8. Understanding DevOps Principles and CI/CD Chevron down icon Chevron up icon
9. Testing Your Enterprise Application Chevron down icon Chevron up icon
10. Deciding on the Best Cloud-Based Solution Chevron down icon Chevron up icon
11. Applying a Microservice Architecture to Your Enterprise Application Chevron down icon Chevron up icon
12. Choosing Your Data Storage in the Cloud Chevron down icon Chevron up icon
13. Interacting with Data in C# – Entity Framework Core Chevron down icon Chevron up icon
14. Implementing Microservices with .NET Chevron down icon Chevron up icon
15. Applying Service-Oriented Architectures with .NET Chevron down icon Chevron up icon
16. Working with Serverless – Azure Functions Chevron down icon Chevron up icon
17. Presenting ASP.NET Core Chevron down icon Chevron up icon
18. Implementing Frontend Microservices with ASP.NET Core Chevron down icon Chevron up icon
19. Client Frameworks: Blazor Chevron down icon Chevron up icon
20. Kubernetes Chevron down icon Chevron up icon
21. Case Study Chevron down icon Chevron up icon
22. Case Study Extension: Developing .NET Microservices for Kubernetes Chevron down icon Chevron up icon
23. Answers Chevron down icon Chevron up icon
24. Other Books You May Enjoy Chevron down icon Chevron up icon
25. Index Chevron down icon Chevron up icon

Customer reviews

Top Reviews
Rating distribution
Full star icon Full star icon Full star icon Half star icon Empty star icon 3.5
(2 Ratings)
5 star 50%
4 star 0%
3 star 0%
2 star 50%
1 star 0%
Filter icon Filter
Top Reviews

Filter reviews by

Michael Börner Feb 20, 2024
Full star icon Full star icon Empty star icon Empty star icon Empty star icon 2
Es wird Azure benötigt, was vorher ich vorher nicht gesehen habe, sonst hätte ich es nicht gekauft
Feefo Verified review Feefo image
N/A Feb 14, 2024
Full star icon Full star icon Full star icon Full star icon Full star icon 5
Livre clair et complet. À jour avec les derniers versions. Après avoir essayé des livres français je recommande l'ouvrage en priorité
Feefo Verified review Feefo image
Get free access to Packt library with over 7500+ books and video courses for 7 days!
Start Free Trial


How do I buy and download an eBook? Chevron down icon Chevron up icon

Where there is an eBook version of a title available, you can buy it from the book details for that title. Add either the standalone eBook or the eBook and print book bundle to your shopping cart. Your eBook will show in your cart as a product on its own. After completing checkout and payment in the normal way, you will receive your receipt on the screen containing a link to a personalised PDF download file. This link will remain active for 30 days. You can download backup copies of the file by logging in to your account at any time.

If you already have Adobe reader installed, then clicking on the link will download and open the PDF file directly. If you don't, then save the PDF file on your machine and download the Reader to view it.

Please Note: Packt eBooks are non-returnable and non-refundable.

Packt eBook and Licensing When you buy an eBook from Packt Publishing, completing your purchase means you accept the terms of our licence agreement. Please read the full text of the agreement. In it we have tried to balance the need for the ebook to be usable for you the reader with our needs to protect the rights of us as Publishers and of our authors. In summary, the agreement says:

  • You may make copies of your eBook for your own use onto any machine
  • You may not pass copies of the eBook on to anyone else
How can I make a purchase on your website? Chevron down icon Chevron up icon

If you want to purchase a video course, eBook or Bundle (Print+eBook) please follow below steps:

  1. Register on our website using your email address and the password.
  2. Search for the title by name or ISBN using the search option.
  3. Select the title you want to purchase.
  4. Choose the format you wish to purchase the title in; if you order the Print Book, you get a free eBook copy of the same title. 
  5. Proceed with the checkout process (payment to be made using Credit Card, Debit Cart, or PayPal)
Where can I access support around an eBook? Chevron down icon Chevron up icon
  • If you experience a problem with using or installing Adobe Reader, the contact Adobe directly.
  • To view the errata for the book, see and view the pages for the title you have.
  • To view your account details or to download a new copy of the book go to
  • To contact us directly if a problem is not resolved, use
What eBook formats do Packt support? Chevron down icon Chevron up icon

Our eBooks are currently available in a variety of formats such as PDF and ePubs. In the future, this may well change with trends and development in technology, but please note that our PDFs are not Adobe eBook Reader format, which has greater restrictions on security.

You will need to use Adobe Reader v9 or later in order to read Packt's PDF eBooks.

What are the benefits of eBooks? Chevron down icon Chevron up icon
  • You can get the information you need immediately
  • You can easily take them with you on a laptop
  • You can download them an unlimited number of times
  • You can print them out
  • They are copy-paste enabled
  • They are searchable
  • There is no password protection
  • They are lower price than print
  • They save resources and space
What is an eBook? Chevron down icon Chevron up icon

Packt eBooks are a complete electronic version of the print edition, available in PDF and ePub formats. Every piece of content down to the page numbering is the same. Because we save the costs of printing and shipping the book to you, we are able to offer eBooks at a lower cost than print editions.

When you have purchased an eBook, simply login to your account and click on the link in Your Download Area. We recommend you saving the file to your hard drive before opening it.

For optimal viewing of our eBooks, we recommend you download and install the free Adobe Reader version 9.